12

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

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

4

2 回答 2

15

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

[res.on.functions]/p2,第 2.7 条:

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

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

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

对于 C++17,委员会 2015 年 5 月会议通过的N4510vector放宽了、listforward_list.

于 2015-06-25T10:18:16.537 回答
1

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

于 2015-06-25T10:23:13.543 回答