Нельзя избежать создания временного аргумента для конструктора Foo
с emplace_back
. Если вы используете аргумент типа Foo
, то это временный объект, который будет передан в конструктор размещенного объекта. В этом случае push_back
будет в равной степени эффективен.
Чтобы реально использовать преимущества замещения, ваш тип должен иметь конструктор, который принимает несколько легких аргументов, которые можно использовать для создания более дорогихобъект. Таким образом, только временные объекты являются легкими объектами. Для непосредственного исключения из возвращаемого значения этот конструктор может принимать только один аргумент.
Пример:
struct ExpensiveMove {
explicit ExpensiveMove(double d) {
std::cout << "construct\n";
std::fill(arr.begin(), arr.end(), d);
}
ExpensiveMove(const ExpensiveMove&) { std::cout << "expensive copy\n"; }
ExpensiveMove(ExpensiveMove&&) { std::cout << "expensive move\n"; }
ExpensiveMove& operator=(const ExpensiveMove&) { std::cout << "expensive copy ass\n"; return *this; }
ExpensiveMove& operator=(ExpensiveMove&&) { std::cout << "expensive move ass\n"; return *this; }
std::array<double, 1024> arr;
};
double calculate()
{
return 4.2;
}
int main() {
std::vector<ExpensiveMove> arr;
arr.emplace_back(calculate());
}
В этом примере нет временных значений типа ExpensiveMove
. Есть временный дубль, который не имеет значения.