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”tostd::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
成员。此外,astd::forward
将导致移动,只有std::forward
将导致左值。在编辑之前,这是不正确的,但使用引用折叠的模板解决方案适用于指定情况(据我所知,通过检查std::is_右值_参考
和std::is_左值_参考
)。因此,如果这个答案仍然有问题,请给我一个提示,而不是在没有任何评论的情况下通过否决票。这看起来甚至不需要显式副本。@Xeo:是的,它确实需要显式副本;问题明确地说,t
的唯一构造函数采用BigClass&
,特别是没有constructorT::T(const BigClass&)
的使用将为您创建和绑定临时文件。