以下代码似乎在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
。
这是保证工作还是未定义的行为?
答案 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,放宽了vector
,list
和forward_list
的此规则。
答案 1 :(得分:1)
根据cppreference.com中的“模板参数”部分,这可能在C ++ 17标准中有效(取决于容器的实际用途),但在C ++ 14及更早版本中则不行。您可能正在使用实现C ++ 17标准部分的编译器版本。