std::vector 前向声明类型

std::vector on forward declared type

以下代码似乎可以在 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.

的指针

这是保证有效,还是未定义的行为?

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

[res.on.functions]/p2,项目符号 2.7:

In particular, the effects are undefined in the following cases:

  • [...]
  • if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

在 C++14 及更早版本中,std::vector 不会 "specifically allow" 这个。所以行为是未定义的。

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

根据 cppreference.com 的 "Template Parameters" 部分,这可能适用于 C++17 标准(取决于容器的实际使用情况),但不适用于 C++14 及更早版本。可能您正在使用实现这部分 C++17 标准的编译器版本。