C++ std::move的反义词是否存在?
当移动尚未被隐式允许时(例如当从函数返回本地对象时),可用于显式允许移动语义 现在,我想知道(特别是在本地返回和隐式移动的上下文中,),是否存在与C++ std::move的反义词是否存在?,c++,c++11,move-semantics,C++,C++11,Move Semantics,当移动尚未被隐式允许时(例如当从函数返回本地对象时),可用于显式允许移动语义 现在,我想知道(特别是在本地返回和隐式移动的上下文中,),是否存在与std::move相反的东西会阻止移动对象(但仍然允许复制) 这有意义吗?防止移动对象的解决方案是将对象的移动构造函数设置为私有,这样对象就不能移动,但可以复制 移动示例: enter code here #include <iostream> class A { public: std::string s; A() :
std::move
相反的东西会阻止移动对象(但仍然允许复制)
这有意义吗?防止移动对象的解决方案是将对象的移动构造函数设置为私有,这样对象就不能移动,但可以复制 移动示例:
enter code here
#include <iostream>
class A {
public:
std::string s;
A() : s("test") {}
A(const A& o) : s(o.s) { std::cout << "move failed!\n";}
A(A&& o) : s(std::move(o.s)) { std::cout << "move was succesfull!\n"; }
};
int main(int argc, const char * argv[])
{
A firsObject;
A secondObject = std::move(firsObject);
return 0;
}
在此处输入代码
#包括
甲级{
公众:
std::字符串s;
A():s(“测试”){}
A(const A&o):s(o.s){std::coutstd::move
将左值转换为右值,它基本上是通过static\u cast
实现的。最接近我所能想到的相反的是这两种类型的强制转换:
static_cast<T &>(/*rvalue-expression*/)
static_cast<const T&>(/*rvalue-expression*/)
当您在此行之后使用a
时,它将是一个左值。即使a
声明为右值引用,也是如此:
int &&a = 3;
在这里,a
也变成了左值(基本上是因为它“有一个名称”)
我能想象显式强制转换具有任何相关效果的唯一情况是我上面的第一个示例。在这里,当处理诸如3
之类的prvalue或通过复制从函数调用返回的临时值时,唯一合法的强制转换是到常量引用(不允许非常量引用绑定到prvalue).我确实有一个问题:为什么需要这个?甚至可能没有要返回的本地对象,它可以通过(N)RVO-a理论上的return std::copy_only(v)创建
会妨碍编译器这样做。删除移动构造/赋值。仍然不会阻止RVO。std::unmove
。也可能是std::demove
。或者可能是antimove
或者dontmove
?不移动就移动?movebackintime
,moveelephantoblockthepath
?否?@Xeo-我不需要它:-)只是好奇而已。记录在案:我不认为这是一个重复的链接问题。(只是实际阅读问题及其答案,看看为什么)。静态强制转换为常量引用是否真的会阻止函数返回时的隐式移动?否,函数返回的类型最终由函数声明中的返回类型决定。如果在返回前强制转换对象,它最终将再次强制转换为正式返回类型。如果n type是一个非引用,您将得到一个prvalue;如果它是一个右值引用,您将得到一个xvalue。(但这相当于std::move
的行为:如果函数返回类型被定义为左值引用,std::move
在返回之前不会启用移动语义。)所以,无论出于什么扭曲的原因,如果想要阻止fn返回的隐式移动,那么必须创建第二个局部变量来保存返回,然后返回该局部变量,对吗?(T local1;…T local2=local1;/*@MartinBa,但是,正如您在评论中所说,return local2;
仍然可能触发移动,对吗?这会以什么方式阻止移动?@MartinBa啊,是的,是的。当然,local1
将超出return
的范围,在那之前,local2
还没有被删除但是,就像std::move
不能覆盖声明的返回类型一样,我建议的cast不能做到这一点。但是我相信std::move
的要点是指导编译器选择正确的函数重载(也就是说,它通常应用于函数参数,而不是在返回语句中)。在这个函数中,建议的cast是“反移动”的一个很好的候选者。那么,为什么要使用构造函数呢?@R.Martinho Fernandes,你是对的,移动构造函数可以省略。在上面的例子中,我考虑了一种情况,当你需要它时,这样你可以声明一个朋友类/方法,在必要时仍然可以使用移动构造函数。当然,这无法解决返回ca时的隐式移动中特别强调的sequestion@MartinBa:您的意思是像returnunmove(expr);
例如,它也可以在那里工作。是的,returnunmove(local_变量);
@MartinBa:是的,unmove也将在那里工作,并抑制返回值的RVO和move构造-强制复制构造。这与@jogojapan在对其答案的评论中所说的相矛盾
#include <iostream>
void f(const int &)
{ std::cout << "const-lval-ref" << std::endl; }
void f(int &&)
{ std::cout << "rval-ref" << std::endl; }
int main()
{
f(static_cast<const int &>(3));
return 0;
}
int a = 3;
int &&a = 3;
template<class T>
T& unmove(T&& t)
{
return t;
}
void f(const int&); // copy version
void f(int&&); // move version
int main()
{
int i = ...;
f(42); // calls move version
f(move(i)); // calls move version
f(i); // calls copy version
f(unmove(42)); // calls copy version
f(unmove(move(i))); // calls copy version
f(unmove(i)); // calls copy version
}