我从下面的地址学习有向图, 基本照着写了 但是编译的过程中还是报了下面的错误, 使用的visual studio2022, C++20
[color=var(--theme-link-color, var(--theme-secondary-400))]https://github.com/carlesmartin85/procpp5e/tree/65aedda6a92745beca48a5041411465a33cdf4cd/code/c25_code/03_DirectedGraphBasic
报错的位置
下面是各个文件和代码
directed_graph.cppm
[C++] 纯文本查看 复制代码 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;
[[nodiscard]] size_t size() const noexcept;
[[nodiscard]] 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);
[[nodiscard]] 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),
[node_index](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>
void directed_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[index].value();
}
template<typename T>
const T& directed_graph<T>::operator[](size_t index) const
{
return m_nodes[index].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[index].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.cpp[C++] 纯文本查看 复制代码 module;
#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>;
[[nodiscard]] adjacency_list_type& get_adjacent_nodes_indices();
[[nodiscard]] 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);
[[nodiscard]] T& value() noexcept;
[[nodiscard]] 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.cppm[C++] 纯文本查看 复制代码 module;
#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[index] };
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.cpp[C++] 纯文本查看 复制代码 import 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;
}
|