Предупреждение: возвращение ссылки на временные

У меня есть такая функция

const string &SomeClass::Foo(int Value)
{
    if (Value < 0 or Value > 10)
        return "";
    else
        return SomeClass::StaticMember[i];
}

Я получаю warning: returning reference to temporary. Почему это? Я думал, что оба значения, возвращаемые функцией (ссылка на const char * "" и ссылка на статический член) не могут быть временными.

Ответ 1

Это пример, когда происходит нежелательное неявное преобразование. "" не является std::string, поэтому компилятор пытается найти способ превратить его в один. И с помощью конструктора string( const char* str ) он преуспевает в этой попытке. Теперь был создан временный экземпляр std::string, который будет удален в конце вызова метода. Таким образом, очевидно, что не рекомендуется ссылаться на экземпляр, который больше не будет существовать после вызова метода.

Я предлагаю вам либо изменить тип возврата на const string, либо сохранить "" в членной или статической переменной SomeClass.

Ответ 2

Это пример попытки оптимизировать код в С++. Я сделал это, все сделали это... Стоит отметить, что это классический пример, который может возвращать оптимизацию значений.

Как и ttvd, правильный ответ заключается в том, чтобы возвращать const std::string, а не ссылку на него и позволить компилятору оптимизировать его.

Если вы доверяете интерпретатору вашего любимого языка для оптимизации позади вас, вы также не должны пытаться быть слишком умным с С++.

Ответ 3

Проблема в первой строке. "" будет преобразован в std::string, так как он имеет действительный конструктор, который принимает char*. Это std::string будет анонимным объектом, который является временным, и вы возвращаете его ссылку.

Ответ 4

Как сказал Shaggy Frog, он преобразует "" во временный объект std::string, и поскольку ваша подпись метода std::string & он пытается вернуть ссылку на него, поэтому вы получите предупреждение. Одним из способов может быть возврат std::string по значению (const std::string SomeClass:: Foo (..)).

Ответ 5

Другая возможность избежать - объявить то, что вы хотите вернуть как статическое, и просто использовать return by reference