The result ?: Is an rvalue, a new object if one of the arguments is an rvalue. To create this rvalue, the compiler must copy any result.
if (some_condition) S().f(); // Compiler knows that it rvalue else my_other_S.f(); // Compiler knows that it lvalue
This is for the same reason that you cannot do
struct B { private: B(const B&); }; struct C { C(B&); C(const B&); }; int main() { B b; C c(some_condition ? b : B()); }
I changed my example because the old one was a little suck. You can clearly see here that it is not possible to compile this expression because the compiler cannot know which constructor to call. Of course, in this case, the compiler can force both arguments to const B& , but for some reason this is not very relevant, it will not.
Edit: No, no, because there is no way to compile this expression, since important data about it (rvalue or lvalue) changes at run time. The compiler is trying to fix this problem for you by converting it to rvalue by creating a copy, but it cannot, because it cannot copy, so it cannot compile.
Puppy source share