Переходить от * this в методе rvalue? - PullRequest
10 голосов
/ 12 июня 2010

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

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

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

1 Ответ

4 голосов
/ 24 декабря 2011

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

§9.3.2 [class.this] p1

В теле нестатического (9.3) членаfunction, ключевое слово 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 (единственный компилятор Iзнаю, что реализует ref-квалификаторы), я получаю следующий вывод:

$ clang ++ -std = c ++ 0x -stdlib = libc ++ -pedantic -Wall t.cpp
$ ./a.out
copy ctor // # 1
move ctor // # 2

...