Нет способа обойти это, если вы буквально хотите сохранить код таким, какой он есть: что касается стандарта, то std::vector<T>
может буквально содержать элементы типа T
, и, таким образом, у вас есть циклический взаимная зависимость, при которой Edge
содержит Node
, а Node
содержит Edge
, что не имеет смысла.
(Фактическая формулировка заключается в том, что создание экземпляра шаблона контейнера стандартной библиотеки для неполного типа является неопределенным поведением.)
Типичным способом решения этой проблемы является идиома PIMPL, при которой вы предоставляете только указатель на элемент:
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 описывает изящное решение для абстрагирования этого шаблона чистым и привлекательным способом.
(В качестве альтернативы вы также можете сделать Edge::node
указателем.)