This is a two part question. Is it ok to assign the return value of a function to a reference? Such as
Foo FuncBar()
{
return Foo();
}
// some where
You're not "assigning" to a reference, you're binding to a reference.
That's only proper when the type is const and the context is one where there is automatic lifetime extension of the temporary.
In general, when Foo isn't a const type your examples should fail to compile. Unfortunately, they may compile with one common compiler, due to language extensions implemented by that compiler. It is a good idea to try out examples (and also ordinary code!) with at least two compilers.
CONST defined.
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();
}
If you haven't already done so, it can be a good idea to do that now.
Foo &myFoo = FuncBar();
Will not compile. it should be:
const Foo &myFoo = FuncBar();
because FuncBar() returns a temporary object (i.e., rvalue) and only lvalues can be bound to references to non-const.
Is it safe?
Yes it is safe.
C++ standard specifies that binding a temporary object to a reference to const lengthens the lifetime of the temporary to the lifetime of the reference itself, and thus avoids what would otherwise be a common dangling-reference error.
Foo myFoo = FuncBar();
Is Copy Initialization.
It creates a copy of the object returned by FuncBar() and then uses that copy to initalize myFoo. myFoo is an separate object after the statement is executed.
const Foo &myFoo = FuncBar();
Binds the temporary returned by FuncBar() to the reference myFoo, note that myFoo is just an alias to the returned temporary and not a separate object.