4

std::move可用于在尚未隐式允许移动时显式允许移动语义(例如通常在从函数返回本地对象时)。

现在,我想知道(尤其是在本地返回和隐式移动的上下文中),是否存在与其相反的东西std::move阻止移动对象(但仍然允许复制)。

这甚至有意义吗?

4

3 回答 3

4

std::move将左值转换为右值,它本质上是通过static_cast. 最接近我能想到的相反的是这两种类型转换:

static_cast<T &>(/*rvalue-expression*/)
static_cast<const T&>(/*rvalue-expression*/)

这方面的一个例子可以在下面看到:

#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;
}

将纯右值3转换为const int &确保f选择左值重载。

在大多数情况下,您可以自动获得这种从右值到左值的修改,只需分配给一个变量:

int a = 3;

当您a在此行之后使用时,它将是一个左值。即使a声明为右值引用也是如此:

int &&a = 3;

这里也a变成了一个左值(基本上是因为它“有名字”)。

我可以想象显式强制转换具有任何相关效果的唯一情况是我上面的第一个示例。在那里,当处理3通过复制从函数调用返回的纯右值或临时值时,唯一合法的强制转换是 const-reference(不允许非 const-reference 绑定到纯右值)。

于 2013-07-09T08:29:48.750 回答
0

防止对象被移动的解决方案是将对象的移动构造函数设为私有,这样对象就不能被移动但可以被复制。

移动示例:

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;
}

禁用移动的示例:

#include <iostream>

class A {
public:
    std::string s;
    A() : s("test") {}
    A(const A& o) : s(o.s) { std::cout << "move failed!\n";}

private:
    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;
}
于 2013-07-09T08:25:33.107 回答
0
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
}
于 2013-07-09T10:54:51.103 回答