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

tml*_*len 10 c++ stl forward-declaration c++11 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();
}
Run Code Online (Sandbox Code Playgroud)

std::vector<A>声明数据成员时,A仍然是不完整的类型.同样在使用std::vector<B>B只向前声明class B;.它应该工作,std::vector因为它只包含一个指针A.

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

T.C*_*.C. 13

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

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

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

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

在C++ 14及更早版本中,std::vector并未"特别允许"这一点.所以行为是不确定的.

对于C++ 17,N4510,在委员会2015年5月会议上通过,放宽此规则vector,listforward_list.