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为部分容器添加不完整的类型支持,但仅限于vector
、list
和forward_list
。
考虑与之前 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为部分容器添加不完整的类型支持,但仅限于vector
、list
和forward_list
。