Actually after further investigation, it appears that Visual Studio is patently wrong. The reason for the error is not because of operator resolution issues, it's because of an apparent compiler limitation that does not allow references to undefined types to be returned from a function if they are not assigned. C2027 says that references to undefined types are not allowed, but that is not the case; if their example code is changed to the following it compiles fine:
A& a = CreateA();
It just doesn't work if the return value is unassigned as in their example.
Per section 5.2.2 of the C++ standard, the result type of a function call that returns an lvalue reference is an lvalue, so an incomplete type should be fine.
Since the operator << returns a reference, and it is not being assigned, the same error is being invoked.
A workaround for your code could then be this:
void format(std::ostream &out, const foo &x) { std::ostream& t = out << x; }which should compile fine.
Update: so, apparently the reason that it doesn't work in VS is because VS is unable to convert an undefined type to type void, and a function with the return value unassigned is equivalent to casting to type void, i.e.
(void)CreateA();
The C++ standard states that "Any expression can be explicitly converted to type cv void, in which case it becomes a discarded-value expression."
Therefore VS is wrong and the others are right.
Edited by krippy2k8, 10 August 2012 - 08:23 PM.