xihahaNextYear 发表于 2024-7-4 01:38

C++20 中遇到wstringstream 打印的错误

我从下面的地址学习有向图, 基本照着写了 但是编译的过程中还是报了下面的错误, 使用的visual studio2022, C++20
https://github.com/carlesmartin85/procpp5e/tree/65aedda6a92745beca48a5041411465a33cdf4cd/code/c25_code/03_DirectedGraphBasic


下面是各个文件和代码
directed_graph.cppm
module;

#include <cstddef>

export module directed_graph;
import directed_graph.node;
import <vector>;
import <utility>;
import <set>;
import <algorithm>;

namespace ProCpp
{
    export template<typename T>
    class directed_graph
    {
    public:
      bool insert(const T& node_value);
      bool insert(T&& node_value);

      bool erase(const T& node_value);

      bool insert_edge(const T& from_node_value, const T& to_node_value);

      bool erase_edge(const T& from_node_value, const T& to_node_value);

      void clear() noexcept;

      T& operator[](size_t index);
      const T& operator[](size_t index) const;

      bool operator==(const directed_graph& rhs) const;
      bool operator!=(const directed_graph& rhs) const;

      void swap(directed_graph& other_graph) noexcept;
      [] size_t size() const noexcept;

      [] std::set<T> get_adjacent_nodes_values(const T& node_value) const;
    private:
      friend details::graph_node<T>;
      using nodes_container_type = std::vector<details::graph_node<T>>;
      nodes_container_type m_nodes;

      typename nodes_container_type::iterator findNode(const T& node_value);
      typename nodes_container_type::const_iterator findNode(const T& node_value) const;
      std::size_t get_index_of_node(const typename nodes_container_type::const_iterator& node) const noexcept;
      void remove_all_link_to(typename nodes_container_type::const_iterator node_first);
      [] std::set<T> get_adjacent_nodes_values(const typename details::graph_node<T>::adjacency_list_type& indices) const;
    };

    template<typename T>
    typename directed_graph<T>::nodes_container_type::iterator directed_graph<T>::findNode(const T& node_value)
    {
      return std::find_if(std::begin(m_nodes), std::end(m_nodes), [&node_value](const auto& node) {
            return node.value() == node_value;
            });
    }

    template<typename T>
    typename directed_graph<T>::nodes_container_type::const_iterator directed_graph<T>::findNode(const T& node_value) const
    {
      return const_cast<directed_graph<T>*>(this)->findNode(node_value);
    }

    template<typename T>
    bool directed_graph<T>::insert(T&& node_value)
    {
      auto iter{ findNode(node_value) };
      if (iter != std::end(m_nodes))
      {
            return false;
      }

      m_nodes.emplace_back(this, std::move(node_value));
      return true;
    }

    template<typename T>
    bool directed_graph<T>::insert(const T& node_value)
    {
      T copy{ node_value };
      return insert(std::move(copy));
    }

    template<typename T>
    bool directed_graph<T>::insert_edge(const T& from_node_value, const T& to_node_value)
    {
      const auto from{ findNode(from_node_value) };
      const auto to{ findNode(to_node_value) };

      if (from == std::end(m_nodes) || to == std::end(m_nodes))
      {
            return false;
      }

      const size_t to_index{ get_index_of_node(to) };
      return from->get_adjacent_nodes_indices().insert(to_index).second;
    }

    template<typename T>
    size_t directed_graph<T>::get_index_of_node(const typename nodes_container_type::const_iterator& node) const noexcept
    {
      const auto index{ std::distance(std::cbegin(m_nodes), node) };
      return static_cast<size_t>(index);
    }

    template<typename T>
    void directed_graph<T>::remove_all_link_to(typename nodes_container_type::const_iterator node_iter)
    {
      const size_t node_index{ get_index_of_node(node_iter) };
      for (auto&& node : m_nodes)
      {
            auto& adjacencyIndices{ node.get_adjacent_nodes_indices() };
            adjacencyIndices.erase(node_index);
            std::vector<size_t> indices(std::begin(adjacencyIndices), std::end(adjacencyIndices));
            std::for_each(std::begin(indices), std::end(indices),
                (size_t& index) {
                  if (index > node_index)
                  {
                        --index;
                  }
                }
            );
            adjacencyIndices.clear();
            adjacencyIndices.insert(std::begin(indices), std::end(indices));
      }
    }

    template<typename T>
    bool directed_graph<T>::erase(const T& node_value)
    {
      auto iter{ findNode(node_value) };
      if (iter == std::end(m_nodes))
      {
            return false;
      }

      remove_all_link_to(iter);
      m_nodes.erase(iter);
      return true;
    }

    template<typename T>
    bool directed_graph<T>::erase_edge(const T& from_node_value, const T& to_node_value)
    {
      const auto from{ findNode(from_node_value) };
      const auto to{ findNode(to_node_value) };
      const auto endIter{ std::end(m_nodes) };
      if (from == endIter || to == endIter)
      {
            return false;
      }

      const size_t to_index{ get_index_of_node(to) };
      from->get_adjacent_nodes_indices().erase(to_index);
      return true;
    }

    template<typename T>
    void directed_graph<T>::clear() noexcept
    {
      m_nodes.clear();
    }

    template<typename T>
    voiddirected_graph<T>::swap(directed_graph& other) noexcept
    {
      m_nodes.swap(other.m_nodes);
    }

    export template<typename T>
      void swap(directed_graph<T>& first, directed_graph<T>& second)
    {
      first.swap(second);
    }

    template<typename T>
    T& directed_graph<T>::operator[](size_t index)
    {
      return m_nodes.value();
    }

    template<typename T>
    const T& directed_graph<T>::operator[](size_t index) const
    {
      return m_nodes.value();
    }

    template<typename T>
    bool directed_graph<T>::operator==(const directed_graph& rhs)const
    {
      if (m_nodes.size() != rhs.m_nodes.size())
      {
            return false;
      }

      for (auto&& node : m_nodes)
      {
            const auto rhsNodeIter{ rhs.findNode(node.value()) };
            if (rhsNodeIter == std::end(m_nodes))
            {
                return false;
            }

            const auto adjacent_values_lhs{ get_adjacent_nodes_values(node.get_adjacent_nodes_indices()) };
            const auto adjacent_values_rhs{ rhs.get_adjacent_nodes_values(rhsNodeIter->get_adjacent_nodes_indices()) };

            if (adjacent_values_lhs != adjacent_values_rhs)
            {
                return false;
            }
      }

      return true;
    }

    template<typename T>
    std::set<T> directed_graph<T>::get_adjacent_nodes_values(const typename details::graph_node<T>::adjacency_list_type& indices) const
    {
      std::set<T> values;
      for (auto&& index : indices)
      {
            values.insert(m_nodes.value());
      }
      return values;
    }

    template<typename T>
    std::set<T> directed_graph<T>::get_adjacent_nodes_values(const T& node_value) const
    {
      auto iter{ findNode(node_value) };
      if (iter == std::end(m_nodes))
      {
            return std::set<T>{};
      }

      return get_adjacent_nodes_values(iter->get_adjacent_nodes_indices());
    }

   
    template<typename T>
    bool directed_graph<T>::operator!=(const directed_graph& rhs) const
    {
      return !(*this == rhs);
    }


    template<typename T>
    size_t directed_graph<T>::size() const noexcept
    {
      return m_nodes.size();
    }

}



graph_node.cppmodule;

#include <cstdlib>

export module directed_graph.node;

import <set>;

namespace ProCpp
{
    template<typename T>
    class directed_graph;
namespace details
{

    export template<typename T>
    class graph_node
    {
    private:
      friend class directed_graph<T>;
      directed_graph<T>* m_graph;

      using adjacency_list_type = std::set<size_t>;
      [] adjacency_list_type& get_adjacent_nodes_indices();
      [] const adjacency_list_type& get_adjacent_nodes_indices() const;

      T m_data;
      adjacency_list_type m_adjacentNodeIndices;
    public:
      graph_node(directed_graph<T>* graph, const T& t);
      graph_node(directed_graph<T>* graph, T&& t);

      [] T& value() noexcept;
      [] const T& value() const noexcept;

      bool operator==(const graph_node&) const = default;
    };

    template<typename T>
    graph_node<T>::graph_node(directed_graph<T>* graph, const T& t) :m_graph{graph}, m_data{t}
    {

    }

    template<typename T>
    graph_node<T>::graph_node(directed_graph<T>* graph, T&& t) :m_graph{graph}, m_data{std::move(t)} {}

    template<typename T>
    T& graph_node<T>::value()noexcept { return m_data; }

    template<typename T>
    const T& graph_node<T>::value()const noexcept { return m_data; }

    template<typename T>
    typename graph_node<T>::adjacency_list_type& graph_node<T>::get_adjacent_nodes_indices()
    {
      return m_adjacentNodeIndices;
    }

    template<typename T>
    const typename graph_node<T>::adjacency_list_type& graph_node<T>::get_adjacent_nodes_indices() const
    {
      return m_adjacentNodeIndices;
    }

    }
}
目前报错是在这个文件内directed_graph_to_dot.cppmmodule;

#include <cstddef>

export module directed_graph.to_dot;

import directed_graph;
import <string>;
import <string_view>;
import <sstream>;
import <iostream>;
import <format>;

namespace ProCpp
{
      // Returns a given graph in DOT format.
    export template <typename T>
    std::wstring to_dot(const directed_graph<T>& graph, std::wstring_view graph_name)
    {
      std::wstringstream stringstream;

      stringstream << std::format(L"digraph {} {{", graph_name.data()) << std::endl;
      for (size_t index{ 0 }; index < graph.size(); ++index)
      {
            const auto& node_value{ graph };
            const auto adjacent_nodes{ graph.get_adjacent_nodes_values(node_value) };
            if (adjacent_nodes.empty())
            {
                stringstream << node_value << std::endl;
            }
            else
            {
                for (auto&& node : adjacent_nodes)
                {
                  stringstream << std::format(L"{} -> {}", node_value, node) << std::endl;
                }
            }
      }
      stringstream << "}" << std::endl;

      return stringstream.str();
    }
}

test25.cppimport directed_graph;
import directed_graph.node;
import directed_graph.to_dot;
import <iostream>;
import <string>;

using namespace std;
using namespace ProCpp;

template class directed_graph<wstring>;

int main()
{
    directed_graph<int> graph;
    graph.insert(11);
    graph.insert(22);
    graph.insert(33);
    graph.insert(44);
    graph.insert(55);
    graph.insert_edge(11, 33);
    graph.insert_edge(22, 33);
    graph.insert_edge(22, 44);
    graph.insert_edge(22, 55);
    graph.insert_edge(33, 44);
    graph.insert_edge(44, 55);
    wcout << to_dot(graph, L"Graph1");

    system("pause");
    return 0;

}

你好,再见 发表于 2024-7-4 09:37

把stringstream全部改名成wss你看看?

xihahaNextYear 发表于 2024-7-4 22:53

你好,再见 发表于 2024-7-4 09:37
把stringstream全部改名成wss你看看?

我找到解决的方法,是在test25.cpp里import<sstream>
页: [1]
查看完整版本: C++20 中遇到wstringstream 打印的错误