Переместить из * в метод rvalue?

В С++ 11 методы могут быть перегружены, независимо от того, является ли выражение, которое обозначает объект, на котором вызывается метод, lvalue или rvalue. Если я возвращу *this из метода, вызванного через rvalue, мне нужно явно move из *this или нет?

Foo Foo::method() &&
{
    return std::move(*this);   // Is this move required or not?
}

К сожалению, я не могу просто проверить это на моем компиляторе, так как g++ еще не поддерживает эту функцию: (

Ответ 1

Тип *this всегда равен lvalue:

§9.3.2 [class.this] p1

В теле нестатической (9.3) функции-члена ключевое слово this является выражением prvalue, значением которого является адрес объекта, для которого вызывается функция. Тип this в функции-члене класса X X*. [...]

§5.3.1 [expr.unary.op] p1

Унарный оператор * выполняет косвенное обращение: выражение, к которому оно применяется, должно быть указателем на тип объекта или указателем на тип функции, а результат - lvalue, ссылаясь на объект или функцию, на которые указывает выражение.

Поэтому вам нужно 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 = С++ 0x -stdlib = libС++ -pedantic -Wall t.cpp
$./a.out
copy ctor//# 1
move ctor//# 2