g ++ 5中std :: unordered_set编译错误的不完整类型,用clang ++编译

vso*_*tco 2 c++ clang incomplete-type c++11 gcc5

考虑与先前SO问题C++循环依赖混淆相关的代码与邻接列表表示

#include <cstddef>
#include <unordered_set>

class Node;

class Hash {
public:
    std::size_t operator()(const Node &node) const;
};

class Node {
public:
    int data;
    std::unordered_set<Node, Hash> links;
};

inline size_t Hash::operator()(const Node &node) const {
    return node.data;
}

int main()
{

}
Run Code Online (Sandbox Code Playgroud)

使用g ++ 4.9.2或g ++ 5时,此代码无法编译,但是使用clang ++ 3.5进行编译.

g ++吐出的错误始于

error: invalid application of 'sizeof' to incomplete type 'Node' : std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>

问:是否Node有一个声明的时候是一个完整的类型std::unordered_set?看起来g ++或clang ++在这种情况下是错误的.

PS:我知道这种情况可以通过使用a std::shared_ptr<Node>来避免,但是想了解上面代码中的行为.

T.C*_*.C. 8

实例化具有不完整类型的标准库容器是未定义的行为.[res.on.functions]/1,2.5:

1在某些情况下(替换函数,处理函数,用于实例化标准库模板组件的类型的操作),C++标准库依赖于C++程序提供的组件.如果这些组件不符合要求,则标准对实施没有要求.

2特别是,在下列情况下,效果未定义:

  • [...]
  • 如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非特别允许该组件.

两种实现都是正确的.

目前一个提案不完全类型支持添加到一些容器,但它是有限的vector,listforward_list.