Если s
позже не требуется в коде, то это неправильное использование функции emplace_back()
.Это потому, что вы вызываете конструктор копирования класса S
вместо передачи аргументов emplace_back()
, который будет использовать правильный конструктор из S
.
. Рассмотрим следующий код:
#include <iostream>
#include <vector>
struct S
{
S() {std::cout<< " default ctor" <<std::endl;}
S(int) {std::cout<< " user-def ctor" <<std::endl;}
S(const S &) {std::cout<< " copy ctor" <<std::endl;}
S(S &&) {std::cout<< " move ctor" <<std::endl;}
};
int main()
{
std::vector<S> v;
v.reserve(5);
std::cout<< "auto calls: " <<std::endl;
auto s = S();
std::cout<<std::endl;
std::cout<< "emplace_back( s ) calls: " <<std::endl;
v.emplace_back(s);
std::cout<<std::endl;
std::cout<< "emplace_back( std::move(s) ) calls: " <<std::endl;
v.emplace_back(std::move(s));
std::cout<<std::endl;
std::cout<< "emplace_back( S{} ) calls: " <<std::endl;
v.emplace_back(S{});
std::cout<<std::endl;
std::cout<< "emplace_back( ) calls: " <<std::endl;
v.emplace_back();
std::cout<<std::endl;
std::cout<< "emplace_back( 2 ) calls: " <<std::endl;
v.emplace_back(2);
std::cout<<std::endl;
}
Результаты:
auto calls:
default ctor
emplace_back( s ) calls:
copy ctor
emplace_back( std::move(s) ) calls:
move ctor
emplace_back( S{} ) calls:
default ctor
move ctor
emplace_back( ) calls:
default ctor
emplace_back( 2 ) calls:
user-def ctor
Резерв используется для выделения пространства на 5 S
с.Без резервирования пространства выходные данные будут включать дополнительные вызовы для копирующих векторов из вектора.
Когда вы просто передаете аргументы конструктору S
(в данном случае ничего), emplace_back()
создает объект S, используя ctor по умолчанию непосредственно внутри вектора.
Кстати, см. пример в godbolt , который является вашим другом в этих случаях, чтобы точно увидеть, что происходит на заднем плане.