g++5 中 std::unordered_set 编译错误的不完整类型,在 clang++ 中编译
Posted
技术标签:
【中文标题】g++5 中 std::unordered_set 编译错误的不完整类型,在 clang++ 中编译【英文标题】:incomplete type for std::unordered_set compiling error in g++5, compiles in clang++ 【发布时间】:2015-05-08 18:42:34 【问题描述】:考虑与上一个 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>
问题:在声明std::unordered_set
时,Node
是否必须是完整类型?在这种情况下,看起来 g++ 或 clang++ 都是错误的。
PS:我知道这种情况可以通过使用std::shared_ptr<Node>
来避免,但是想了解上面代码中的行为。
【问题讨论】:
【参考方案1】:实例化具有不完整类型的标准库容器是未定义的行为。 [res.on.functions]/1, 2.5:
1 在某些情况下(替换函数、处理函数、 用于实例化标准库模板的类型的操作 组件),C++ 标准库依赖于提供的组件 通过 C++ 程序。如果这些组件不符合他们的要求, 该标准对实施没有任何要求。
2 特别是,在以下情况下效果是不确定的:
[...] 如果在实例化模板组件时将不完整类型 (3.9) 用作模板参数,除非特别允许 该组件。
两种实现都是正确的。
目前有proposal为部分容器添加不完全类型支持,但仅限于vector
、list
和forward_list
。
【讨论】:
嗯,clang++ 甚至没有发出警告,clang++ -std=c++11 -Wall -Wextra -Wpedantic so.cpp
_ +1:我看不出有什么可以反驳这个答案的。
@T.C.谢谢,当场。我从一篇相当古老的 C++ 文章 drdobbs.com/the-standard-librarian-containers-of-inc/184403814 中知道 std::vector
存在问题,但不知道现在标准明确禁止在任何地方使用不完整类型(除非特别允许)。
@vsoftco 它不是“无处不在”,就像标准容器内容一样。
@MattMcNabb [res.on.functions] 适用于任何地方。以上是关于g++5 中 std::unordered_set 编译错误的不完整类型,在 clang++ 中编译的主要内容,如果未能解决你的问题,请参考以下文章
我的班级有一个 toString() 方法,我如何使用它在 std::unordered_set 中进行散列?
std :: unordered_set :: find - 仅为find()构造一个实例
在 std::unordered_set<const char *> 中找不到转换为 const char * 的 std::string