C++ 使用std::experimental::optional实现列表

C++ 使用std::experimental::optional实现列表,c++,list,data-structures,c++14,C++,List,Data Structures,C++14,我想知道是否可以使用std::experimental::optional实现一个单(也可能是双)链表 template <typename T> struct node { std::experimental::optional<node<T>> next; T data; }; 模板 结构节点{ std::实验::可选下一步; T数据; }; 这种设计的优点/缺点是什么?新的c++1z特性可以用来实现Sentinel,还是将它们一起去掉

我想知道是否可以使用
std::experimental::optional
实现一个单(也可能是双)链表

template <typename T>
struct node {
    std::experimental::optional<node<T>> next;
    T data;
};
模板
结构节点{
std::实验::可选下一步;
T数据;
};

这种设计的优点/缺点是什么?新的
c++1z
特性可以用来实现Sentinel,还是将它们一起去掉?这也会扩展到n元树吗?

这是不可能的,因为
可选的
要求
T
是完整的

根据(关于
std::可选
的提案):

类模板optional对T的要求很少:它必须是左值引用类型,或者是满足可破坏性要求的完整对象类型


以这种方式实现链表是不可能的,因为您的
节点
-类型总是不完整的。下面是一个例子来说明这个问题:

#include <iostream>
#include <experimental/optional>

template <typename T>
struct node {
    std::experimental::optional<node<T>> next;
    T data;
};

int main( int, char ** )
{
    std::cout << sizeof( node<int> ) << std::endl;
    return 0;
}
但在实践中,由于内存对齐要求,它更为复杂


在您的情况下,为了知道
可选
的大小,它必须知道
节点
的大小,为此它必须知道
可选
的大小。您尝试过吗?看起来第一个节点将包含所有其他节点作为值而不是指针?不确定其扩展程度。也就是说,
sizeof(node)
必须至少
sizeof(next)+sizeof(data)
并且
sizeof(next)
必须大于
sizeof(node)
…对于
std::experimental::variant
,是否也有相同的要求?@j.dog不确定
std::experimental::variant
,但是
boost::variant
确实需要完整的类型(当不使用
boost::recursive_variant
时,它使用动态分配将其存储在对象之外).提到基本原因,
可选的
本身包含足够的数据来存储
T
,会比只引用标准要好。@Yakk是的,就像所有这些答案一样,我们希望标准强加这样的要求是有原因的,最终这才是有趣的原因。
template <typename T>
struct node {
    std::experimental::optional<node<T>> next;
    T data;
};