Why do Visual Studio 2010 and Visual Studio 2012 fail to compile this code?
Codepad.org, Xcode, gcc, LLVM, Clang all have no problem but Visual Studio poops the bed:
struct S {
template <class T> inline operator T () const { return T (); }
};
int main () {
// NOTE: "S()" denotes construction in these examples
struct F {
void operator() (bool) { }
static void toint (int) { }
static void tostr (char const*) { }
};
bool b1 = S (); // Okay
bool b2 (S ()); // Okay
F () (S ()); // Okay
F::toint (S ());// Okay
F::tostr (S ());// Okay
S () || false; // Error: error C2676: binary '||' : 'vf::S' does
// not define this operator or a conversion to a type
// acceptable to the predefined operator
return 0;
}
Adding the explicit
keyword doesn't change a thing for gcc or clang. The error message produced is:
error C2676: binary '||' : 'S' does not define this operator or a
conversion to a type acceptable to the predefined operator
It's a bug, at least in C++03 (not sure about C++11).
According to the overload resolution rules in C++03 §13.3.1.2, the built-in ||
operator is selected, since no user-defined ||
operator is defined for S
.
§5.15/1 says:
The
||
operator groups left-to-right. The operands are both implicitly converted tobool
(clause 4). [...]
§12.3/2 says:
User-defined conversions are applied only where they are unambiguous (10.2, 12.3.2). [...]
§12.3/5:
User-defined conversions are used implicitly only if they are unambiguous. [...] Function overload resolution (13.3.3) selects the best conversion function to perform the conversion.
§13.3.2/3:
Second, for
F
to be a viable function, there shall exist for each argument an implicit conversion sequence (13.3.3.1) that converts that argument to the corresponding parameter ofF
.
Clearly S
defines a user-defined conversion to bool
. The built-in ||
operator is a viable function for the overload resolution, and since it's the only one, it's the best. So the expression is well-formed.
Also of note is §4/3, which says:
An expression
e
can be implicitly converted to a typeT
if and only if the declaration “T t=e;
” is well- formed, for some invented temporary variablet
(8.5). [...]
So I'm curious whether Visual Studio also produces an error for the statement bool b = S();
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With