The following code does not compile (at least in the versions of g++/clang I tried). godbolt link
struct T {
std::unique_ptr<double> p;
T() {}
T(const T&) {}
T(T&&) {}
};
struct X {
T t;
std::vector<std::unique_ptr<int>> f;
};
int main()
{
std::vector<X> y;
X x;
y.emplace_back(std::move(x));
}
Specifically, the compilers seem to complain about a call to a deleted copy constructor on vector<unique_ptr<int>>
which doesn't make sense to me.
The requirements seem to more or less say that emplace_back
should work if there is a move constructor. Since there are no user-declared constructors for X
and also no members / base classes that can't be moved from, I believe that a move constructor should be implicitly declared and not deleted.
Some 'fixes':
- remove the
T
member - remove the
vector<unique_ptr<int>>
member - add another
unique_ptr
- define move constructor explicitly for X
Could someone explain why the original code is ill-formed? And why the 'fixes' (mostly the first 3 and especially the 3rd) make the code compile?