2

考虑与前面的 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()
{

}

此代码在使用 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:我知道可以通过使用 astd::shared_ptr<Node>来避免这种情况,但是想了解上面代码中的行为。

4

1 回答 1

8

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

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

2 特别是,在以下情况下的影响是不确定的:

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

两种实现都是正确的。

目前有提议为某些容器添加不完全类型支持,但仅限于vector,listforward_list.

于 2015-03-07T03:21:35.353 回答