std::vector on forward declared type

1.9k views Asked by At

The following code seems to work correctly on Clang++ and 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();
}

When the data member std::vector<A> is declared, A is still an incomplete type. Same when using std::vector<B> and B was only forward declared with class B;. It should work with std::vector since it only contains a pointer-to-A.

Is this guaranteed to work, or undefined behavior?

2

There are 2 answers

0
T.C. On BEST ANSWER

This is undefined behavior in C++14 and earlier; well-defined in C++17 (if it's 17).

[res.on.functions]/p2, bullet 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.

In C++14 and earlier, std::vector does not "specifically allow" this. So the behavior is undefined.

For C++17, N4510, adopted at the committee's May 2015 meeting, relaxes this rule for vector, list, and forward_list.

1
Aleksei Fedotov On

According to section "Template Parameters" from cppreference.com this might work (depending on the actual usage of the container) in C++17 standard, but not in C++14 and earlier. Probably you are using versions of the compilers that implement this part of C++17 standard.