ссылка типа "std :: string &" (не константная) не может быть инициализирована - PullRequest
5 голосов
/ 25 мая 2011

Когда я пытаюсь скомпилировать следующую функцию, я получаю сообщение об ошибке.

string& foo(){
return "Hello World";
}


Error:
1   IntelliSense: a reference of type "std::string &" (not const-qualified) cannot be initialized with a value of type "const char [12]"

Ответы [ 5 ]

21 голосов
/ 25 мая 2011

Есть две проблемы с вашим кодом.Во-первых, "Hello World!" - это char const[13], а не std::string.Таким образом, компилятор должен (неявно) преобразовать его в std::string.Результатом преобразования является временное (rvalue в C ++ - говорят), и вы не можете инициализировать ссылку на неконстантный с временным.Во-вторых, даже если вы могли (или вы объявили функцию, возвращающую ссылку на const), вы возвращаете ссылку на что-то, что немедленно выйдет из области видимости (и, следовательно, будет уничтожено);любое использование полученной ссылки приведет к неопределенному поведению.

Реальный вопрос: почему ссылка?Если вы на самом деле не ссылаетесь на что-то в объекте с более длительным временем жизни, имея в виду, что клиентский код изменяет это (обычно это не очень хорошая идея, но есть заметные исключения, такие как operator[] вектора), вы должны вернутьпо значению.

10 голосов
/ 25 мая 2011

«Hello World» - это не строка, это массив символов. Компилятору c ++ необходимо преобразовать это в строковое значение, а не в строковую ссылку (потому что это не строка), поэтому ваша функция должна выглядеть так:

string foo(){
    return "Hello World";
}

Чтобы развернуть (по запросу OP), компилятор делает что-то вроде этого:

string foo(){
    char a[] = "Hello World";
    string s( a ); 
    return s;
}

Значение s копируется из функции конструктором копирования std :: string.

2 голосов
/ 25 мая 2011

Вы указываете компилятору возвращать временную строку std :: string, созданную из массива char "Hello World".Нужно положить это куда-нибудь и поручить кому-нибудь за это почистить.Вы можете сделать это несколькими способами:

  • Вернуть auto_ptr
  • Вернуть строковый объект
  • Вернуть константную ссылку на строковый объект (хотя это оставляетменя с вопросом, кто это очищает?)
  • (только c ++ 0x) Возвращает ссылку правой рукой на std :: string.(std :: string &&)

Второе, вероятно, будет самым простым.Компилятор будет использовать RVO (оптимизация возвращаемого значения), чтобы удалить вызванную этим копию.

0 голосов
/ 25 мая 2011

Просто сделай это.

const string foo() {
    return string("Hello World");
}
0 голосов
/ 25 мая 2011

Я думаю, что вы хотите:

string foo(){
    return "Hello World";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...