Вопрос

У меня есть три вызова функций, которые, я думаю, должны обрабатываться (примерно) одинаково, но очевидно, что это не так.Я пытаюсь понять, почему один из трех не компилируется (g ++ -std= c ++ 0x).

// Minimal example to reproduce a compile bug I want to understand.

#include <iostream>
#include <string>

using namespace std;


void bar(const string &&x) { cout << "bar: " << x << endl; }

string returns_a_string() { return string("cow"); }

int main( int argc, char *argv[] )
{
    bar(string("horse"));     // ok
    bar(returns_a_string());  // ok
    string aardvark = "aardvark";
    bar(aardvark);            // not ok, fails to compile, error in next comment
    /*
      rvalue-min.cpp:29:22: error: cannot bind ‘std::string {aka std::basic_string<char>}’ lvalue to ‘const string&& {aka const std::basic_string<char>&&}’
      rvalue-min.cpp:10:6: error:   initializing argument 1 of ‘void barR(const string&&)’
    */
}

Этот вопрос немного похож на C ++ 0x ссылки на rvalue - привязка lvalues-rvalue, но, если там есть ответ, приношу свои извинения, я не смог его извлечь.

Что я хочу, так это иметь возможность вызывать мою функцию bar () с любым типом строки и заставить ее просто работать.Этого достаточно, чтобы определить void barR(const string &x), но я бы действительно хотел понять, почему.

Большое спасибо за любую помощь в понимании того, почему третий звонок отличается.

Это было полезно?

Решение

Назначение ссылочных параметров r-значения - конкретно определить, когда объект является r-значением.Потому что, если объект является r-значением, то функция знает, что он больше не будет использоваться, поэтому она может делать с ним все, что захочет.Если бы l-значение могло привязываться к ссылке на r-значение, это означало бы, что обнаружение, о котором я говорил, на самом деле не имело места.

Если вы хотите передать l-значение одной из этих функций, вам необходимо использовать std::move.Передача объекта через std::move обращаться к функции, которая принимает ссылку на r-значение, все равно что сказать: "вот, возьми этот объект, вырви из него кишки, мне все равно, что с ним будет".

Для ваших целей правильный ответ - сделать ссылку на параметр const .R-значение совершенно нормально привязано к ссылке const.За исключением конструкторов перемещения, создание ссылочных параметров с r-значением почти никогда не является правильным решением.

Другие советы

Вам нужно использовать std::move.Это работает нормально :

bar(std::move(aardvark));
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top