Rvalue ref и совершенная пересылка - PullRequest
4 голосов
/ 28 июля 2011

Я прочитал несколько статей о &&, и мне просто любопытно, если есть:

void fnc_1(int&& p)
{
//...
}

void fnc(int&& r)
{
fnc_1(r);//am I suppose to/should I? call it like so:fnc_1(std::forward(r)) 
}

или достаточно просто пропустить 'r'?

Ответы [ 2 ]

6 голосов
/ 28 июля 2011

fnc_1(r) не скомпилируется, потому что r - это lvalue, как и любая другая переменная, независимо от типа.Да, верно, именованные ссылки на rvalue являются lvalues, а не rvalues.

fnc_1(std::forward(r)) также не будет компилироваться, потому что std::forward специально разработан, чтобы не выводить аргумент шаблона.

Дляпередать rvalue, сработает любое из следующих действий:

fnc_1(std::move(r))
fnc_1(std::forward<int&&>(r))  
fnc_1(std::forward<int>(r))  

Использование std::move - это идиоматический способ приведения lvalue к rvalue, поэтому я рекомендую использовать это.

3 голосов
/ 28 июля 2011

Шаблон std::forward обычно предназначен для зависимых типов. Пожалуйста, внимательно прочитайте этот вопрос , чтобы увидеть, применим ли он здесь. Это сложный предмет для освоения, поэтому не стесняйтесь обновлять свой вопрос соответствующими сведениями о вашей конкретной проблеме (использование rvalue-ссылок для целых чисел не очень интересно ...).

Я полагаю, что ваш вопрос касается понимания основных свойств rvalue ссылок. Эмпирическое правило, которое нужно запомнить:

  • все, что имеет имя, является lvalue (постоянным или нет).
  • все, что не имеет имени, является значением.
  • Типы с && привязываются к значениям.

Если у вас есть функция ...

void foo(SomeClass&& x)
{
    // ... then here x has type SomeClass& !
}

затем внутри тела, x - это имя, и, следовательно, значение l . Это действительно имеет тип SomeClass&. Вы должны использовать std::move, чтобы превратить SomeClass& в SomeClass&&:

void bar(SomeClass&& x)
{
    // Since `x` has a name here, it is a Lvalue.
    // Therefore it has type SomeClass&, what the signature doesn't indicate.

    // We thus have to explicitly turn it into a rvalue:
    foo(std::move(x));
}
...