привязка lvalue к rvalue, ссылка перемещает ctor и возвращает функцию - PullRequest
0 голосов
/ 29 июля 2011

Согласно тому, что я знаю, недопустимо связывать lvalue в ссылку на rvalue.И, во-вторых, выражение lvalue можно узнать по тому, что оно может быть префиксом оператора адреса-адресата, (&)

У меня небольшие проблемы, если эти два предложения корректны со следующими кодами:

 #include<iostream>

struct Foo
{
    Foo(Foo&& other)
    {
        std::cout << "move ctor called";
    }

    Foo(const Foo& other)
    {
        std::cout << "copy ctor called";
    }

    Foo(){}
};

Foo return_foo()
{
    Foo f;
    return f;
}


void main()
{  
    Foo f = return_foo(); // Move ctor is called, but return_foo() is a lvalue ?? 
    std::cin.ignore();    
}

Где я не прав?

Ответы [ 2 ]

4 голосов
/ 29 июля 2011

return_foo() возвращает значение prvalue (потому что возвращает временный объект без имени).Цитата из §3.10 / 1, выделение мое:

prvalue («чистое» rvalue) - это rvalue, которое не является xvalue.[Пример: Результатом вызова функции, тип возвращаемой которой не является ссылкой, является значение prvalue. Значение литерала, такого как 12, 7.3e5 или true, также является значением prvalue.- конец примера]

2 голосов
/ 29 июля 2011

Существует специальное правило, которое позволяет возвращать временное значение в качестве значения r, а именно следующее эквивалентно - явная версия "Мне больше не нужно":

T foo()
{
  T t(a, b, ...); // constructed somehow
  /* ... */
  return std::move(t);
}

int main()
{
  T t = foo(); // we can move-construct this
}

... и неявная версия:

T foo()
{
  T t(a, b, ...);
  /* ... */
  return t;  // implicitly allow moving
}

Все это происходит после оптимизации возвращаемого значения. Это означает, что возврат по значению на самом деле довольно эффективен во многих ситуациях.

...