我想知道是否可以使用std::experimental::optional
实现单个(并且可能是双重)链接列表。
template <typename T>
struct node {
std::experimental::optional<node<T>> next;
T data;
};
这种设计有哪些优点/缺点?可以使用新的c++1z
功能来实现哨兵,还是完全摆脱它们?这会扩展到 n-ary 树吗?
答案 0 :(得分:18)
无法以这种方式实现链接列表,因为您的node
- 类型将始终不完整。这是一个more complete example来说明问题:
#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;
}
重点是optional<T>
要求T
完整,但在您定义next
时,node
不完整。 optional<T>
需要完整类型的原因是它将T
直接存储在optional
对象中,即它不在堆上分配内存。因此,它必须知道T
的大小。在内部,它包含sizeof( T )
的缓冲区。在内存布局方面,您可以将optional<T>
视为
template <class T>
struct optional
{
bool _containsValue;
char _buffer[ sizeof( T ) ];
};
但实际上,由于内存对齐要求,它更复杂。
在您的情况下,为了知道optional<node>
的大小,它必须知道node
的大小,为此必须知道optional<node>
的大小。
答案 1 :(得分:10)
这是不可能的,因为optional<T>
需要T
才能完成。
根据N3672(std::optional
的提案):
类模板可选对T提出的要求很少:它必须是左值引用类型,或满足Destructible要求的完整对象类型。