Reputation: 45
I have a class Node, and a struct Edge. But when the struct is written before the class, the struct complains for no knowing what is distance. It is the same for the the way around, when the struct is define after, the classe complain for not knowing what is a Edge (the type of the vector).
//This is my header file
typedef struct Edge Edge;
struct Edge{
Node node;
int distance;
};
class Node
{
private:
std::vector<Edge> vectorOfEdges;
};
How do I get around this error? Thank you.
Upvotes: 1
Views: 2062
Reputation: 477010
There is no way around this if you literally want to keep the code as it is: As far as the standard is concerned, std::vector<T>
might as well literally contain elements of type T
, and thus you have a cyclic mutual dependence whereby Edge
contains a Node
and Node
contains an Edge
, which does not make sense.
(The actual wording is that a instantiating a standard library container template on an incomplete type is undefined behaviour.)
The typical way around this is the PIMPL idiom, by which you only provide a pointer to the element:
struct Edge;
class Node
{
std::unique_ptr<std::vector<Edge>> pVecImpl;
public:
Node() : pVecImpl(::new std::vector<Edge>) { }
// ...
};
struct Edge
{
// as before
};
Herb Sutter's GotW #101 describes a neat solution to abstract this pattern in a clean and attractive fashion.
(Alternatively you can also make Edge::node
into a pointer.)
Upvotes: 2
Reputation: 726539
Your definition is circular: it tries to put a Node
inside an Edge
, and a vector of edges inside a Node
. You need to make one of these a pointer, for example, like this:
class Node;
struct Edge{
Node *node;
int distance;
};
class Node {
private:
std::vector<Edge> vectorOfEdges;
};
P.S. You were missing a semicolon after the struct.
Upvotes: 1