C++ 双功能到std::move?

C++ 双功能到std::move?,c++,c++11,move-semantics,C++,C++11,Move Semantics,假设我有一个只有一个构造函数的类: class T { public: T(BigClass&& big) : big(std::move(big)) {} ... SomeBigClass }; 在大多数情况下,构造函数是在临时对象上调用的,但在一个地方,我需要创建BigClass的显式副本,因为它不是临时对象,将在循环中多次使用: void foo(const BigClass& big) { while (...) { T t(std:

假设我有一个只有一个构造函数的类:

class T {
 public:
  T(BigClass&& big) : big(std::move(big)) {}
  ...

  SomeBigClass
};
在大多数情况下,构造函数是在临时对象上调用的,但在一个地方,我需要创建BigClass的显式副本,因为它不是临时对象,将在循环中多次使用:

void foo(const BigClass& big) {
  while (...) {
    T t(std::make_a_copy(big));
    ...
  }
}
在C++11或C++14中是否有任何函数“dual”to
std::move
,可以替代上面的make_a_copy


编辑:一些澄清。

如果你可以操作
T
,你可以模板化构造函数

#include <iostream>
using namespace std;
class B
{
  int x;
public:
  B (int i) : x(i) { }
  B (B && b) : x(b.x) { cout << "B moved (" << x << ")" << endl; }
  B (B const  & b) : x(b.x)  { cout << "B copied (" << x << ")" << endl; }
};


class A
{
  B b;
public:
  template<typename TB>
  A (TB && init_b) : b(std::forward<TB &&>(init_b)) { }
};

B foo (void) { B x(3); return x; }


int main (void)
{
  A a1(foo());
  B b1(4);
  A a2(b1);
  return 0;
}
#包括
使用名称空间std;
B类
{
int x;
公众:
B(inti):x(i){}

B(B&&B):x(B.x){cout为什么不能复制
BigClass
对象

void foo(const BigClass& big) {
  while (...) {
    T t{ BigClass(big) };
    ...
  }
}

这使得一个临时的
BigClass
被移动到
T

中,编写它并不困难:

template <typename T>
T make_temp(const T& x) { return x; }
模板
T make_temp(const T&x){return x;}

当使用一个参数调用时,可能会有一个标准函数碰巧做到这一点,但没有一个函数是为这种不寻常的模式设计的。

如果您可能需要制作一个副本,那么您是否也应该提供一个
t(BigClass const&big)
constructor,然后调用它?为什么你需要复制一个临时的,而不是移动?这似乎有点不合情理。可能有人应该拒绝我的编辑。如果你想写尽可能少的函数,两个“核心”是复制构造函数,和
swap
。移动构造函数、复制赋值和移动赋值可以用复制构造函数和swap编写。没有复制构造函数…没有捷径。这个问题与标题所说的完全无关。在拥有rva的情况下,需要使用
std::Move
的双重属性lue引用表达式,您需要一个可修改的左值引用(如果您这样编写它,它将不会绑定,并且从右值创建临时值也不会起作用,因为它只能初始化
const
lvalue引用)。这里的情况并非如此,您的情况正好相反;可以使用
std::move
进行编译,但这并不是您想要的。解决方案是首先复制
大的
值,这与您的
类T
无关。您的测试存在严重缺陷。您在第二行复制
A
,哪一行是course复制
b
成员。此外,a
std::forward
将导致移动,只有
std::forward
将导致左值。在编辑之前,这是不正确的,但使用引用折叠的模板解决方案适用于指定情况(据我所知,通过检查
std::is_右值_参考
std::is_左值_参考
)。因此,如果这个答案仍然有问题,请给我一个提示,而不是在没有任何评论的情况下通过否决票。这看起来甚至不需要显式副本。@Xeo:是的,它确实需要显式副本;问题明确地说,
t
的唯一构造函数采用
BigClass&
,特别是没有constructor
T::T(const BigClass&)
的使用将为您创建和绑定临时文件。