A non-const reference (like B& base
) can only bind to an lvalue.
F::getC()
returns a C
object by value, so the call expression f.getC()
is an rvalue, not an lvalue.
The reason that N n(C());
works, however, is due to an unrelated problem.
This does not declare an object. It declares a function named n
that returns N
and takes a parameter of type "pointer to a function that has no parameters and returns C
."
This is one manifestation of a language peculiarity known as the most vexing parse. To change this to declare an object, you'd need one of the following:
N n = C(); // Use copy initialization
N n((C())); // Use more parentheses
Both of these would fail to compile, though, because both would attempt to bind the result of the rvalue expression C()
to the non-const reference B& base
.
A const reference (like B const& base
) can bind to an rvalue, as can an rvalue reference (like B&& base
) in C++11.