Consider this simple example of having a map type as a member of a class where the value type of the map is the enclosing class:
#include <map>
#include <unordered_map>
// compiles
class trie {
std::map<char, trie> data_;
};
// fails to compile on GCC, Clang, works on MSVC
class trie2 {
std::unordered_map<char, trie2> data_;
};
When the map type is std::map
, this seems to compile fine everywhere. For Clang and GCC, on all versions I've tried that support C++17 up to the latest (Clang 11, GCC 10.2), using std::unordered_map
fails to compile with some variation of:
In file included from /opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/stl_algobase.h:64,
from /opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/stl_tree.h:63,
from /opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/map:60,
from <source>:1:
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/stl_pair.h: In instantiation of 'struct std::pair<const char, trie2>':
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/ext/aligned_buffer.h:91:28: required from 'struct __gnu_cxx::__aligned_buffer<std::pair<const char, trie2> >'
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/hashtable_policy.h:233:43: required from 'struct std::__detail::_Hash_node_value_base<std::pair<const char, trie2> >'
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/hashtable_policy.h:279:12: required from 'struct std::__detail::_Hash_node<std::pair<const char, trie2>, false>'
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/hashtable_policy.h:1973:13: required from 'struct std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<const char, trie2>, false> > >'
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/hashtable.h:173:11: required from 'class std::_Hashtable<char, std::pair<const char, trie2>, std::allocator<std::pair<const char, trie2> >, std::__detail::_Select1st, std::equal_to<char>, std::hash<char>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >'
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/unordered_map.h:105:18: required from 'class std::unordered_map<char, trie2>'
<source>:11:37: required from here
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/stl_pair.h:218:11: error: 'std::pair<_T1, _T2>::second' has incomplete type
218 | _T2 second; ///< The second member
| ^~~~~~
<source>:10:7: note: forward declaration of 'class trie2'
10 | class trie2 {
| ^~~~~
Compiler returned: 1
MSVC compiles this example with std::unordered_map
. Is this a bug in the standard library implementations for GCC/Clang or is there some reason according to the standard that this should not be expected to work?