Home > OS >  Why std::vector uses copy constructor instead of move constructor when destructor is marked as poten
Why std::vector uses copy constructor instead of move constructor when destructor is marked as poten

Time:10-11

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:

CodePudding user response:

This is LWG2116. The choice between moving and copying the elements is often expressed as std::is_nothrow_move_constructible, i.e. noexcept(T(T&&)), which also checks the destructor.

  • Related