Исправление 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()