Почему перераспределение векторной копии вместо перемещения элементов? [дубликат]

Возможный дубликат:
Как обеспечить семантику перемещения при увеличении вектора?

insert, push_backи emplace( _back) могут вызвать перераспределение std::vector. Я был озадачен, увидев, что следующий код копируетэлементы вместо перемещенияих при перераспределении контейнера.

#include 
#include 

struct foo {
    int value;

    explicit foo(int value) : value(value) {
        std::cout << "foo(" << value << ")\n";
    }

    foo(foo const& other) noexcept : value(other.value) {
        std::cout << "foo(foo(" << value << "))\n";
    }

    foo(foo&& other) noexcept : value(std::move(other.value)) {
        other.value = -1;
        std::cout << "foo(move(foo(" << value << "))\n";
    }

    ~foo() {
        if (value != -1)
            std::cout << "~foo(" << value << ")\n";
    }
};

int main() {
    std::vector foos;
    foos.emplace_back(1);
    foos.emplace_back(2);
}

На моей конкретной машине с использованием моего конкретного компилятора (GCC 4.7) это напечатает следующее:

foo(1)
foo(2)
foo(foo(1))
~foo(1)
~foo(1)
~foo(2)

Однако при удалении конструктора копирования ( foo(foo const&) = delete;) генерируется следующий (ожидаемый) вывод:

foo(1)
foo(2)
foo(move(foo(1))
~foo(1)
~foo(2)

Почему так? Разве перемещение в целом не будет более эффективным или, по крайней мере, не намного менее эффективным, чем копирование?

Следует отметить, что GCC 4.5.1 делает то, что ожидалось— это регрессия в GCC 4.7 или какая-то хитрая оптимизация, потому что компилятор видит, что мой объект дешево скопировать (но как ?!)?

Также обратите внимание, что я удостоверился, что это вызваноперераспределением, экспериментально поместив foos.reserve(2);перед вставками; это не приводит к выполнению ни копирования, ни перемещения.

28
задан Community 23 May 2017 в 12:34
поделиться