I was playing around with a class Foo
, that defined an implicit operator bool()
. I used Foo
as a return type for several functions, so I could get an information about what had been done and call the Foo::operator bool()
to get whether the operation had performed successfully.
Out of curiosity, I also tried an explicit call of the conversion operator while using Foo
:
if(!func().operator bool()) // func returned Foo
throw std::logic_error("operation was not successful");
That worked fine. Then, I suddenly decided to dump the Foo
class and go with simple bool
but I forgot to remove .operator bool()
call on the function return value. And so I discovered a set of strange behaviors of Visual C++ 12.0 compiler (Visual Studio 2013).
None of the explicit calls of conversion operators to bool
are valid in GCC:request for member ‘operator bool’ in ‘true’, which is of non-class type ‘bool’
Now, the behavior I get with Visual Studio:
#include <iostream>
using std::cout;
using std::endl;
bool func()
{
return true;
}
int main()
{
bool b = true.operator bool();
cout << b << endl; // error C4700: uninitialized local variable 'b' used
// evaluates to true (probably like b would do if it compiled)
if(false.operator bool())
cout << "a" << endl;
cout << func().operator bool() << endl; // prints nothing
int m = 10;
cout << m.operator int() << endl; // prints nothing
// correctly gives error: left of '.<' must have class/struct/union
cout << m.operator <(10) << endl;
}
Even the intellisense is right and shows Error: expression must have a class type
.
Is there an explanation to all this? A bug? An (unwanted) extension? What is it?
Nice find! The standard definitely makes this ill-formed with a diagnostic required, [expr.ref]:
A postfix expression followed by a dot
.
or an arrow->
, optionally followed by the keywordtemplate
(14.2), and then followed by an id-expression, is a postfix expression. [..] For the first option (dot) the first expression shall have complete class type.
Also, not an extension: Would be one hell of a nonsensical extension. It seems that VC++ implements bool
with some internal (class-like?) type:
In Visual C++ 5.0 and later,
bool
is implemented as a built-in type with a size of 1 byte.
That type's class-like semantics are apparently not fully suppressed. Even
bool b;
b.operator std::string();
compiles (giving a seemingly empty string
), implying that the internal class has a conversion operator template.
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