3

According to documentation, std::vector elements should be MoveInsertable for push_back and emplace_back, in case the capacity needs to be increased.

However in the example below the copy constructor is used during resizing, even though class A has a move constructor. If I delete the copy constructor, only then the move constructor is used.

#include <iostream>
#include <string>
#include <vector>

struct A
{
    A() { std::cout << "creating A\n"; }
    A(const A& that) { std::cout << "copying A\n"; }
    A(A&&that) { std::cout << "moving A\n"; }
};

int main()
{
    std::vector<A> vec;
    std::cout << "size=" << vec.size() << ", capacity=" << vec.capacity() << "\n";
    vec.emplace_back();
    std::cout << "size=" << vec.size() << ", capacity=" << vec.capacity() << "\n";
    for (size_t i = vec.size(), n = vec.capacity() + 1; i < n; i++) {
        vec.emplace_back();
    }
    std::cout << "size=" << vec.size() << ", capacity=" << vec.capacity() << "\n";
}

Output

size=0, capacity=0
creating A
size=1, capacity=1
creating A
copying A
size=2, capacity=2

The question is - shouldn't std::vector prefer my move constructor over the copy constructor?

rustyx
  • 80,671
  • 25
  • 200
  • 267
  • 3
    Try making the move constructor (and possibly move assignment) `nothrow`. – Baum mit Augen Feb 18 '17 at 16:45
  • Is VC++ STL implementation bugged in this area? This code compiled on VS 2015 results in `creating` `moving` `creating` sequence. Move c-tor not marked by `noexcept` can be picked if `A` is not CopyInsertable but it is. – mpiatek Feb 18 '17 at 17:15

0 Answers0