LINUX.ORG.RU

История изменений

Исправление rumgot, (текущая версия) :

Вспоминал я тут наше это обсуждение и вот к чему пришел. Если использовать сразу std::initializer_list - то будет конечно копирование, когда начнешь доставать значения из std::initializer_list и присваивать их далее. Но эй, ведь если будешь использовать функцию, принимающую аргумент вида std::vector<A>&& и будешь передавать список инициализации - то все равно будет использоваться конструктор std::vector(std::initializer_list<T>) т.е. при этом все равно будет сразу создаваться объект std::initializer_list с переданными значениями и далее уже из него эти значения будут скопированы в std::vector, т.е. один фиг копирование будет.

Вот иллюстрация написанного:

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

using namespace std;

struct A {
    A() { cout << "A()" << endl; }
    A(const string& n) : name(n) { cout << "A(const string&)" << endl; }
    A(const A& a) : name(a.name) { cout << "A(const A&)" << endl; }
    A(A&& a) : name(move(a.name)) { cout << "A(A&&)" << endl; }

    ~A() { cout << "~A()" << endl; }

    A& operator=(const A& a) {
        cout << "operator=(const A&)" << endl;
        name = a.name;
        return *this;
    }

    A& operator=(A&& a) {
        cout << "operator=(A&&)" << endl;
        name = move(a.name);
        return *this;
    }

    string name;
};

void f(vector<A>&& args) {
    cout << "void f(vector<A>&& args)" << endl;
    // do something
}

// void f(initializer_list<A> args) {
//     cout << "void f(initializer_list<A> args)" << endl;
//     // do something
// }

int main() { f({{"first"}, {"second"}, {"third"}}); }

Вывод:

A(const string&)
A(const string&)
A(const string&)
A(const A&)
A(const A&)
A(const A&)
~A()
~A()
~A()
~A()
~A()
~A()

Таким образом все же использование std::vector получается избыточным и добавляет некоторые минимальные накладные расходы.

Исходная версия rumgot, :

Вспоминал я тут наше это обсуждение и вот к чему пришел. Если использовать сразу std::initializer_list - то будет конечно копирование, когда начнешь доставать значения из std::initializer_list и присваивать их далее. Но эй, ведь если будешь использовать функцию, принимающую аргумент вида std::vector<A>&& и будешь передавать список инициализации - то все равно будет использоваться конструктор std::vector(std::initializer_list<T>) т.е. при этом все равно будет сразу создаваться объект std::initializer_list с переданными значениями и далее уже из него эти значения будут скопированы в std::vector, т.е. один фиг копирование будет.

Вот иллюстрация написанного:

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

using namespace std;

struct A {
    A() { cout << "A()" << endl; }
    A(const string& n) : name(n) { cout << "A(const string&)" << endl; }
    A(const A& a) : name(a.name) { cout << "A(const A&)" << endl; }
    A(A&& a) : name(move(a.name)) { cout << "A(A&&)" << endl; }

    ~A() { cout << "~A()" << endl; }

    A& operator=(const A& a) {
        cout << "operator=(const A&)" << endl;
        name = a.name;
        return *this;
    }

    A& operator=(A&& a) {
        cout << "operator=(A&&)" << endl;
        name = move(a.name);
        return *this;
    }

    string name;
};

void f(vector<A>&& args) {
    cout << "void f(vector<A>&& args)" << endl;
    // do something
}

// void f(initializer_list<A> args) {
//     cout << "void f(initializer_list<A> args)" << endl;
//     // do something
// }

int main() { f({{"first"}, {"second"}, {"third"}}); }

Вывод:

A(const string&)
A(const string&)
A(const string&)
A(const A&)
A(const A&)
A(const A&)
~A()
~A()
~A()
~A()
~A()
~A()