C++ 使用emplace\u back避免移动构造函数调用的最佳方法?

C++ 使用emplace\u back避免移动构造函数调用的最佳方法?,c++,c++11,c++17,emplace,C++,C++11,C++17,Emplace,我刚刚了解到。根据对该问题的答复: 当您执行时返回T(),这将初始化 通过prvalue执行功能。由于该函数返回T,因此不需要临时值 创建;prvalue的初始化只是直接初始化 返回值 需要理解的是,由于返回值是prvalue, 它还不是一个物体。它只是一个对象的初始值设定项, 就像T()一样 所以我想知道,除了: T f() {return T();} T t = f(); 所以我用emplace\u back编写了这段代码来测试它: #include <vector> #inc

我刚刚了解到。根据对该问题的答复:

当您执行
时返回T(),这将初始化
通过
prvalue
执行功能。由于该函数返回T,因此不需要临时值 创建;
prvalue
的初始化只是直接初始化 返回值

需要理解的是,由于返回值是
prvalue
, 它还不是一个物体。它只是一个对象的初始值设定项, 就像
T()
一样

所以我想知道,除了:

T f() {return T();}
T t = f();
所以我用
emplace\u 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());
}
尽管
prvalue
被直接传递到
emplace\u back
中,但似乎仍然会调用move构造函数,我认为它可以用来直接构造一个对象,而不是用来构造一个临时对象然后移动它

除了执行类似于
g()
函数的操作之外,还有没有更优雅的方法可以避免使用
emplace\u back
调用move构造函数

似乎移动构造函数仍然被调用,即使prvalue被直接传递到emplace_back

您认为可以,但没有将其传递到函数中。您给它一个prvalue作为参数,是的,但是
emplace\u back
接受的是一组转发引用。一个引用必须引用一个对象,所以一个引用必须是一个对象,并被移动


使用
emplace\u back
的正确方法是将初始化对象的参数传递给它。这样,您就不需要移动向量的元素类型(尽管您可能需要移动/复制参数)。

因此,当将prvalue传递到接受任何类型引用(常量引用或右值引用)的任何函数时,需要构造一个临时变量?@user2108462-Yes。绑定到引用是发生临时物化的地方。它必须发生,这样我们才能得到所引用的对象。@StoryTeller,啊,我的阅读理解失败,评论本身实际上是prvalue。当然,最酷的是将
v.emplace_称回(f)即,不要立即执行f(),而是将工厂函数传递到emplace中,以便在适当的时间执行。但是,对于一个简单的对象来说,用std::function来做这件事太过分了。@gemtylor-难道不能用表达式模板或等效的技术来做类似的事情吗?大概不过,如果没有锅炉板,那就太好了。
emplace_back with rvalue 
int ctor called
emplace_back with f()
int ctor called
move ctor called
emplace_back with g()
int ctor called