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

incomplete type for std::unordered_set compiling error in g++5, compiles in clang++

考虑与之前 SO 问题相关的代码

#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()
{

}

此代码在使用 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>

问题:声明std::unordered_set时,Node是否必须是完整类型?看起来在这种情况下 g++ 或 clang++ 是错误的。

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

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

1 In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++ standard library depends on components supplied by a C++ program. If these components do not meet their requirements, the Standard places no requirements on the implementation.

2 In particular, the effects are undefined in the following cases:

  • [...]
  • if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

两种实现都是正确的。

目前有proposal为部分容器添加不完整的类型支持,但仅限于vectorlistforward_list