std :: vector在前向声明的类型上

时间:2015-06-25 10:13:47

标签: c++ c++11 stl forward-declaration c++17

以下代码似乎在Clang ++和GCC上正常工作:

#include <vector>

class A {
private:
    int i;
    std::vector<A> children;
public:
    A& add();
};

A& A::add() { children.emplace_back(); return children.back(); }

int main() {
    A a;
    A& a2 = a.add();
}

声明数据成员std::vector<A>时,A仍然是不完整的类型。使用std::vector<B>B时相同,只能使用class B;向前声明。 它应该与std::vector一起使用,因为它只包含一个指针 - A

这是保证工作还是未定义的行为?

2 个答案:

答案 0 :(得分:13)

这是C ++ 14及更早版本中的未定义行为;在C ++ 17中明确定义(如果它是17)。

[res.on.functions] / p2,bullet 2.7:

  

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

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

在C ++ 14及更早版本中,std::vector没有&#34;特别允许&#34;这个。因此行为未定义。

对于C ++ 17,在委员会2015年5月的会议上通过的N4510,放宽了vectorlistforward_list的此规则。

答案 1 :(得分:1)

根据cppreference.com中的“模板参数”部分,这可能在C ++ 17标准中有效(取决于容器的实际用途),但在C ++ 14及更早版本中则不行。您可能正在使用实现C ++ 17标准部分的编译器版本。