Назначить возвращаемое значение из функции в ссылку С++?
Это вопрос из двух частей. Можно ли присвоить возвращаемое значение функции ссылке? Например,
Foo FuncBar()
{
return Foo();
}
// some where else
Foo &myFoo = FuncBar();
Это нормально? Его понимание того, что FuncBar()
возвращает объект Foo, и теперь myFoo
является ссылкой на него.
Вторая часть вопроса. Это оптимизация? Так что если вы делаете это в цикле много времени, лучше делать
Foo &myFoo = FuncBar();
или
Foo myFoo = FuncBar();
И учитывать использование переменных, не будет использовать ref, требующие более медленных различий?
Ответы
Ответ 1
Foo &myFoo = FuncBar();
Не компилируется. это должно быть:
const Foo &myFoo = FuncBar();
потому что FuncBar()
возвращает временный объект (т.е. rvalue), и только lvalues могут быть привязаны к ссылкам на не-const.
Безопасно ли это?
Да, это безопасно.
Стандарт С++ указывает, что привязка временного объекта к ссылке на const продлевает время жизни временного ресурса самой ссылки и, таким образом, позволяет избежать того, что в противном случае было бы общей ошибкой оборванных ссылок.
Foo myFoo = FuncBar();
Является Инициализация копирования.
Он создает копию объекта, возвращаемого FuncBar()
, а затем использует эту копию для инициализации myFoo
. myFoo
- отдельный объект после выполнения оператора.
const Foo &myFoo = FuncBar();
Привязывает временное значение, возвращенное FuncBar()
к ссылке myFoo
, обратите внимание, что myFoo
является просто псевдонимом возвращаемого временного, а не отдельного объекта.
Ответ 2
Вы не "назначаете" ссылку, вы привязываетесь к ссылке.
Это верно только тогда, когда тип const
, и контекст - это тот, где существует автоматическое продление срока службы временного.
В общем случае, когда Foo
не является типом const
, ваши примеры не должны компилироваться. К сожалению, они могут компилироваться с одним общим компилятором из-за языковых расширений, реализованных этим компилятором. Хорошая идея - попробовать примеры (а также обычный код!) С минимум двумя компиляторами.
EDIT: в качестве примера исследовательской работы перед отправкой вопроса вы должны были скомпилировать следующий (или очень похожий) с самым высоким уровнем предупреждения, по крайней мере с двумя компиляторами, с и без const
.
struct Bar {};
#ifdef CONST
typedef Bar const Foo;
#else
typedef Bar Foo;
#endif
Foo FuncBar()
{
return Foo();
}
int main()
{
// som where else
Foo &myFoo = FuncBar();
}
Если вы еще этого не сделали, это может быть хорошей идеей сделать это сейчас.