I was wondering if it is possible to implement a single (and possible double) linked list using std::experimental::optional
.
template <typename T>
struct node {
std::experimental::optional<node<T>> next;
T data;
};
What are the advantages/disadvantages of such a design? Could new c++1z
features be used to implement sentinels, or getting rid of them alltogether? Would this scale up to n-ary trees as well?
It is not possible to implement a linked list in that way, because your node
-type will always be incomplete. Here is a more complete example that illustrates the issue:
#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;
}
The point is that optional<T>
requires T
to be complete but at the point where you define next
, node
is incomplete. The reason why optional<T>
needs a complete type is that it stores T
directly within the optional
object, i.e. it does not allocate memory on the heap. As a result, it has to know the size of T
. Internally, it contains a buffer of sizeof( T )
. In terms of memory layout, you can think of optional<T>
as
template <class T>
struct optional
{
bool _containsValue;
char _buffer[ sizeof( T ) ];
};
but in practice, it is more complicated, due to memory alignment requirements.
In your case, in order to know the size of optional<node>
, it has to know the size of node
and for this it has to know the size of optional<node>
.
It's impossible because the optional<T>
requires T
to be complete.
As per N3672 (the proposal for std::optional
):
Class template optional imposes little requirements on T: it has to be either an lvalue reference type, or a complete object type satisfying the requirements of Destructible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With