【问题标题】:incomplete type for std::unordered_set compiling error in g++5, compiles in clang++g++5 中 std::unordered_set 编译错误的不完整类型,在 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&lt;sizeof(_Tp), std::alignment_of&lt;_Tp&gt;::value&gt;

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

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

【问题讨论】:

    标签: c++ c++11 clang incomplete-type gcc5


    【解决方案1】:

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

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

    2 特别是,在以下情况下效果是不确定的:

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

    两种实现都是正确的。

    目前有proposal为部分容器添加不完全类型支持,但仅限于vectorlistforward_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] 适用于任何地方。
    猜你喜欢
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多