考虑与之前的SO问题相关的代码C++ cyclic dependency confusion with adjacency list representation
#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>
问题:声明Node
时,std::unordered_set
是否必须是完整类型?在这种情况下,看起来g ++或clang ++都是错误的。
PS:我知道使用std::shared_ptr<Node>
可以避免这种情况,但是想了解上面代码中的行为。
答案 0 :(得分:8)
实例化具有不完整类型的标准库容器是未定义的行为。 [res.on.functions] / 1,2.5:
1在某些情况下(替换功能,处理函数, 对用于实例化标准库模板的类型的操作 组件),C ++标准库依赖于提供的组件 通过C ++程序。如果这些组件不符合他们的要求, 标准对实施没有要求。
2特别是,在以下情况下效果未定义:
- [...]
- 如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非特别允许 该组件。
两种实现都是正确的。
目前有一些proposal要为某些容器添加不完整类型支持,但它仅限于vector
,list
和forward_list
。