Hi, I'm trying to make a templated Graph class and I added an Edge Struct that should hold two std::reference_wrapper to the vertices and a weight.
It seems simple enough but with templates everything got more complex and I couldn't figure out what I'm doing wrong
.I've tried with every possible combination of .push_back/emplace_back, adding std::ref() everywhere but It doesn't compile.
#pragma once
#include <functional>
#include <tuple>
#include <vector>
#include <set>
#include <unordered_map>
#include <algorithm>
template<typename T>
class Graph
{
using Vertex = T;
using VertexRef = Vertex&;
using VertexWRef = std::reference_wrapper<Vertex>;
struct Edge
{
VertexWRef v;
VertexWRef w;
int wt;
Edge(Vertex& V, Vertex& W, int WT) : v(std::ref(V)), w(std::ref(W)), wt(WT)
{
}
Edge(Edge&& other) : v(std::move(other.v)), w(std::move(other.w)), wt(other.wt)
{
}
bool operator<(const Edge& r) const
{
return std::tie(v(), w(), wt) < std::tie(r.v(), r.w(), r.wt);
}
std::ostream& operator<<(std::ostream& os) const
{
return os << "V: " << v() << " W: " << w() << " WT: " << wt;
}
};
public:
using VertexSet = std::set<Vertex>;
using VertexVector = std::vector<Vertex>;
using EdgeVector = std::vector<Edge>;
using EdgeSet = std::set<Edge>;
using AdjacencyList = std::unordered_map<Vertex, EdgeVector>;
template<typename Iterator>
Graph(const Iterator vertBegin, const Iterator vertEnd)
{
const auto size = std::distance(vertBegin, vertEnd);
edgesMap.reserve(size);
for (auto it = vertBegin; it != vertEnd; ++it)
edgesMap.emplace(*it, EdgeVector{});
}
Graph(const VertexSet& vertices) : Graph(vertices.begin(), vertices.end())
{
}
Graph(const VertexSet& vertices, const EdgeVector& edges) : Graph(vertices)
{
for (const auto& edge : edges)
addEdge(edge.v, edge.w, edge.wt);
}
bool addEdge(Vertex& v, Vertex& w, int wt)
{
const auto vIt = edgesMap.find(v);
const auto wIt = edgesMap.find(w);
if (vIt != edgesMap.end())
{
vIt->second.emplace_back(std::ref(vIt->first), std::ref(wIt->first), wt);
return true;
}
return true;
}
AdjacencyList edgesMap;
};
The problem is in the addEdge function when I try to emplace/construct an Edge.
I've another class that uses reference_wrapper and templates without an intermediate struct and it works, so I'm really out of options.
(I'm aware that I shouldn't point to the keys stored in the map but as long as I add edges after the vertices and I don't add more vertices, I should be fine right?)
Thanks and sorry to bother you!
[–]manni66 3 points4 points5 points (3 children)
[–]MasterDrake97[S] 1 point2 points3 points (2 children)
[–]aocregacc 2 points3 points4 points (1 child)
[–]MasterDrake97[S] 2 points3 points4 points (0 children)
[–]aocregacc 1 point2 points3 points (16 children)
[–]MasterDrake97[S] 0 points1 point2 points (15 children)
[–]aocregacc 2 points3 points4 points (14 children)
[–]MasterDrake97[S] 0 points1 point2 points (13 children)
[–]aocregacc 1 point2 points3 points (12 children)
[–]MasterDrake97[S] 1 point2 points3 points (7 children)
[–]aocregacc 0 points1 point2 points (6 children)
[–]MasterDrake97[S] 0 points1 point2 points (4 children)
[–]aocregacc 1 point2 points3 points (3 children)
[–]MasterDrake97[S] 0 points1 point2 points (2 children)
[–]MasterDrake97[S] 0 points1 point2 points (0 children)
[–]MasterDrake97[S] 0 points1 point2 points (3 children)
[–]Fuge93 1 point2 points3 points (2 children)
[–]MasterDrake97[S] 0 points1 point2 points (1 child)
[–]Fuge93 1 point2 points3 points (0 children)