我试图创建一个双向树状结构,所以我最终得到了以下结构:
template<typename T>
struct Node
{
T value;
std::vector<Node<T>> kids;
boost::optional<Node<T>> parent { boost::none };
}
template<typename T>
struct Tree
{
std::vector<Node<T>> heads;
};
但是,当我尝试使用此类树/节点作为 unordered_map 中的值时,出现编译错误(MSVC 17.0,C++ 14):
...\boost\include\boost/optional/detail/optional_aligned_storage.hpp(31): error C2027: use of undefined type "Node<std::shared_ptr<Action>>"
经过一番谷歌搜索并询问 Chat-GPT 后,建议更换
boost::optional<Node<T>> parent { boost::none };
与
boost::optional<std::reference_wrapper<Node<T>>> parent { boost::none };
这有效。 然而,老实说,我不知道到底为什么。 谁能解释一下吗?
godbolt 上的最小可重现示例:click;
谁能解释一下吗?
原因是
boost::optional
需要完整类型。当您尝试使用它定义 Node
时,parent
尚未完成(它将在 ;
之后完成,这应该结束结构定义)。
使用
std::reference_wrapper
可以解决问题,因为它使 std::reference_wrapper<Node<T>>
成为类似指针的对象。此类对象不需要被指针指向完整类型(粗略地说,这是因为所有指针都是相似的,无论它们指向什么)。
代替
std::reference_wrapper
,您可以简单地使用原始指针并具有:
Node<T> * parent { nullptr };
您可以使用
nullptr
相当于空的 boost::optional
。