Неэффективный порядок ctor / dtor при перераспределении std :: vector - PullRequest
0 голосов
/ 12 июля 2020

Я поигрался с примером copy elision и заметил странное поведение при перераспределении std :: vector:

[для g cc 10.1 / clang 10.0.0]: При использовании конструкторов перемещения сразу за каждым элементом перемещения следует оператор перемещения. Однако при использовании конструкторов-копий сначала вызываются все ctors, а уже потом dtors. Последнее, возможно, неэффективно, когда класс большой.

Есть ли какое-то требование, чтобы перераспределение с копирующими конструкторами велось таким образом?

Примечание: для i cc 19.0.1 поведение согласован в обоих случаях, но неоптимален.

Вот код , который я использовал для тестирования (попробуйте удалить noexcept из move-ctor):

#include <iostream>
#include <vector>
#include <cassert>

struct Noisy {
    inline static int count = 0;
    Noisy() : data(1000) {
        std::cout << "constructed: " << ++count << "\n";
    }
    Noisy(const Noisy& other) : data(other.data) {
        std::cout << "copy-constructed: " << ++count << "\n";
    }
    Noisy(Noisy&& other) noexcept : data(std::move(other.data)) {
        std::cout << "move-constructed: " << ++count << "\n";
    }
    ~Noisy() {
        std::cout << "destructed: " << --count << "\n";
    }

    std::vector<double> data;
};

std::vector<Noisy> f() {
    std::vector<Noisy> v(2);
    assert(v.size() == v.capacity());
    std::cout << "---------------\n";
    v.emplace_back();
    std::cout << "===============\n";
    return v;
}

int main() {
    f();                     
}
...