std::vector::emplace_back 与左值表达式

std::vector::emplace_back with lvalue expression

本文关键字:表达式 vector emplace std back      更新时间:2023-10-16

使用带有某些结构S的左值的emplace_back是否具有实际意义:

喜欢这个:

std::vector<S> v;
auto s = S(/*...*/);
v.emplace_back(s);

而不仅仅是:

v.emplace_back(/* S constructor arguments */);

或者只是对emplace_back的简单误用,只是因为const S&(因此复制构造函数)是emplace_back内部Args... args的合法实例化,并且没有明确禁止?

正如你已经说过的,传递const S&只会调用复制构造函数。

除非您打算在将s传递给emplace_back之前以某种方式使用它,否则它不一定是明智的。

但是,例如,如果用于创建s的代码特别长,则可以提高可读性,将其和emplace_back代码放在单独的行上。编译器非常擅长优化这种情况,并且无论如何都可能会生成相同的代码(如果复制构造函数是默认的)。基本示例:https://godbolt.org/z/D1FClE

如果它提高了可读性或可维护性,那就去做吧,否则就没有价值。

如果代码后面不需要s,那么它是对emplace_back()函数的误用。这是因为您正在调用S类的复制构造函数,而不是将参数传递给将使用S中的正确构造函数的emplace_back()

请考虑以下代码:

#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

储备用于分配5S秒的空间。在不保留空间的情况下,输出将包括从向量对复制 ctors 的额外调用。

当您只是将参数传递给S的构造函数(在本例中,什么都没有)时,emplace_back()直接在向量内使用默认 ctor 创建一个 S 对象。

顺便说一句,请参阅Godbolt中的示例,在这些情况下,它是您的朋友,以确切地了解背景中发生的事情。