This code:
class Foo {
std::unordered_map<std::string, Foo> x;
};
gives me an error:
/usr/include/c++/4.7/bits/stl_pair.h:94:11:
error: 'std::pair<_T1, _T2>::second' has incomplete type
foo.cpp:4:7: error: forward declaration of 'class Foo'
However, this code compiles just fine:
class Foo {
std::vector<Foo> x;
};
Is this a library/compiler bug?
The C++ standard specifies for the various smart pointers that the template parameter is allowed to be an incomplete type.
The 2017 and later versions of the standard allow a container’s
value_typeto be an incomplete type when instantiating the class template only for the container templatesstd::forward_list,std::list, andstd::vector, and only if the allocator type satisfies the "allocator completeness requirements". The default allocator templatestd::allocatoralways satisfies the allocator completeness requirements. Instantiating any member of the container class template still requires thevalue_typeto be complete.For any other standard container type, this information is not given. In cases where it is unspecified, an implementation is allowed to accept an incomplete type for one container class template and not another, and still be conformant.
To make your code portable, avoid making containers of any type before the type is completed, except in the cases specifically permitted by the standard.
Formally, the general constraint is found in the following rule ([res.on.functions]) which applies to your code:
The three statements specifically allowing an incomplete template argument for
forward_list,list, andvectorare found in sections [forwardlist.overview], [list.overview], and [vector.overview].