使用std :: experimental :: optional来实现列表

时间:2016-08-03 07:09:24

标签: c++ list data-structures c++14

我想知道是否可以使用std::experimental::optional实现单个(并且可能是双重)链接列表。

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

这种设计有哪些优点/缺点?可以使用新的c++1z功能来实现哨兵,还是完全摆脱它们?这会扩展到 n-ary 树吗?

2 个答案:

答案 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才能完成。

根据N3672std::optional的提案):

  

类模板可选对T提出的要求很少:它必须是左值引用类型,或满足Destructible要求的完整对象类型。