Consider the following program:
#include <vector>
#include <iostream>
class A {
int x;
public:
A(int n) noexcept : x(n) { std::cout << "ctor with value\n"; }
A(const A& other) noexcept : x(other.x) { std::cout << "copy ctor\n"; }
A(A&& other) noexcept : x(other.x) { std::cout << "move ctor\n"; }
~A() { std::cout << "dtor\n"; } // (*)
};
int main()
{
std::vector<A> v;
v.emplace_back(123);
v.emplace_back(456);
}
If I run the program, I get (GodBolt):
ctor with value
ctor with value
move ctor
dtor
dtor
dtor
... which is in line with what I would expect. However, if on line (*)
I mark the destructor as potentially throwing, I then get :
ctor with value
ctor with value
copy ctor
dtor
dtor
dtor
... i.e. the copy ctor is used instead of the move ctor. Why is this the case? It doesn't seem copying prevents destructions that moving would necessitate.
Related questions: