使用 emplace_back 避免移动构造函数调用的最佳方法?
Best way to use emplace_back to avoid move constructor call?
我刚刚在 C++17 中了解了保证复制省略。根据对这个问题的回答:
当你执行
return T();
时,这将初始化 通过prvalue
功能。由于该函数返回 T,因此没有临时 创建;prvalue
的初始化只是直接初始化 返回值。要理解的是,由于返回值是一个
prvalue
, 它还不是一个对象。它只是一个对象的初始值设定项, 就像T()
一样。
所以我想知道,这是否适用于以下以外的任何事情:
T f() {return T();}
T t = f();
所以我用emplace_back
编写了这段代码来测试它:
#include <vector>
#include <iostream>
struct BigObj{
BigObj() = default;
BigObj(int) { std::cout << "int ctor called" << std::endl; }
BigObj(const BigObj&){
std::cout << "copy ctor called" << std::endl;
}
BigObj(BigObj&&){
std::cout << "move ctor called" << std::endl;
}
};
BigObj f(){ return BigObj(2); }
int g(){ return 2; }
int main(){
std::vector<BigObj> v;
v.reserve(10);
std::cout << "emplace_back with rvalue n";
v.emplace_back(1+1);
std::cout << "emplace_back with f()n";
v.emplace_back(f());
std::cout << "emplace_back with g()n";
v.emplace_back(g());
}
这是我得到的输出(禁用了复制省略):
emplace_back with rvalue
int ctor called
emplace_back with f()
int ctor called
move ctor called
emplace_back with g()
int ctor called
似乎即使将prvalue
直接传递到emplace_back
中,仍然调用移动构造函数,我认为它可以用来直接构造一个对象,而不是用来构造一个临时然后移动它。
除了执行类似于g()
函数所做的事情之外,有没有一种更优雅的方法可以避免使用emplace_back
进行移动构造函数调用?
似乎即使将 prvalue 直接传递到 emplace_back 中,仍然调用移动构造函数
你认为你这样做了,但你没有把它传递到函数中。你给它一个 prvalue 作为参数,是的,但emplace_back
接受的是一包转发引用。引用必须引用对象,因此临时被具体化并移动。
使用emplace_back
的正确方法是将用于就地初始化对象的参数传递给它。这样你就不需要移动向量的元素类型(尽管您可能需要移动/复制参数)。
相关文章:
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 从类中的对象调用类中的函数的最佳方法
- 使用 emplace_back 避免移动构造函数调用的最佳方法?
- 调用不属于基类的派生类函数的最佳方法是什么?
- 调用模板布尔函数的最佳方法
- C++从函数调用的多个返回中构建字符串向量的最佳方法
- 以错误的方式调用子类中的函数的最佳方法是什么
- 通过网络调用函数的最佳方式是什么
- 从python中的共享对象调用C++函数的最佳方式
- c++调用constchar*参数类型函数的最佳方式
- 当您只需要这些参数之一时,使用通过引用传递的不同参数调用函数的最佳方法
- 永远不要直接调用 std::分配器的成员函数是最佳做法吗?
- 让 C 回调调用 C++ 成员函数的最佳方法