g ++ 5中std :: unordered_set编译错误的不完整类型,用clang ++编译

时间:2015-03-07 03:19:57

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

考虑与之前的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>可以避免这种情况,但是想了解上面代码中的行为。

1 个答案:

答案 0 :(得分:8)

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

  

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

     

2特别是,在以下情况下效果未定义:

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

两种实现都是正确的。

目前有一些proposal要为某些容器添加不完整类型支持,但它仅限于vectorlistforward_list