在一个右值方法中从*this移动?

11
在C++11中,方法可以根据调用该方法的对象表达式是左值还是右值进行重载。如果我从通过右值调用的方法返回*this,我是否需要显式地将*this移动或不需要?
Foo Foo::method() &&
{
    return std::move(*this);   // Is this move required or not?
}

很遗憾,我无法在我的编译器上测试这个功能,因为g++尚未支持此功能 :(


我认为需要使用 move,因为 this 是一个命名的右值引用,类似于函数接受右值参数。但是我不能引用具体章节和条款,所以这不算是一个答案 :) - jalf
@jalf:我期望移动是必需的,因为通常 *E 是一个左值,但谁知道呢 :) 我从未听说过命名的右值。你确定是关于“this”的吗?(无恶意意图!) - fredoverflow
命名右值是一种新术语,引入该术语是为了消除涉及引用的重载调用的歧义。例如,如果我们有 foo(X& x)foo(X&& x),那么 foo(someX) 调用了什么,即 someXX& 还是 X&&?答案是 X&,因为 someX 有一个名称 -- 它是一个命名右值,它是一个 X&。如果我们调用 foo(someX + something),那么它就是 X&&,因为表达式没有"名称"。 - Peter Alexander
someXX&还是X&&?” -> 嗯,两者都不是吧?它只是一个X :) 我不认为someX除了作为左值外还有其他的属性... - fredoverflow
1个回答

5
*this的类型总是一个左值: §9.3.2 [class.this] p1 在非静态成员函数体中,关键字this是一个prvalue表达式,其值是调用该函数的对象的地址。类X的成员函数中,this的类型为X*。[...] §5.3.1 [expr.unary.op] p1 一元运算符*执行间接操作:应用于它的表达式必须是指向对象类型或函数类型的指针,并且结果是一个左值,引用表达式所指的对象或函数。
因此,如果要调用移动构造函数,则需要使用std::move
以下代码片段展示了这一点:
#include <iostream>
#include <utility>

struct test{
  test(){}
  test(test const&){ std::cout << "copy ctor // #1\n"; }
  test(test&&){ std::cout << "move ctor // #2\n"; }

  test f_no_move() &&{ return *this; }
  test f_move() &&{ return std::move(*this); }
};

int main(){
  test().f_no_move(); // #1
  test().f_move(); // #2
}

使用Clang 3.1(我知道唯一实现ref-qualifiers的编译器),我得到以下输出: $ clang++ -std=c++0x -stdlib=libc++ -pedantic -Wall t.cpp $ ./a.out 复制构造函数 // #1 移动构造函数 // #2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接