Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is "operator void" not invoked with cast syntax?

While playing with this answer by user GMan I crafted the following snippet (compiled with Visual C++ 9):

 class Class {  public:      operator void() {}  };   Class object;  static_cast<void>( object );  (void)object;  object.operator void(); 

after stepping over with the debugger I found out that casting to void doesn't invoke Class::operator void(), only the third invokation (with explicitly invoking the operator) actually invokes the operator, the two casts just do nothing.

Why is the operator void not invoked with the cast syntax?

like image 541
sharptooth Avatar asked Oct 27 '10 08:10

sharptooth


People also ask

Which operator is cast operator in C++?

A cast is a special operator that forces one data type to be converted into another. As an operator, a cast is unary and has the same precedence as any other unary operator. const_cast<type> (expr) − The const_cast operator is used to explicitly override const and/or volatile in a cast.

What is the use of cast operator?

Cast operator: () A type cast provides a method for explicit conversion of the type of an object in a specific situation.


1 Answers

The technical reason why is found in §12.3.2:

A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.

The rationale is (likely) to allow §5.2.9/4 to work:

Any expression can be explicitly converted to type “cv void.” The expression value is discarded.

(void)expr to suppose to do nothing for the resulting value of any expression, but if it called your conversion operator it wouldn't be discarding anything. So they ban the use of operator void in conversions.


Why not make it ill-formed to have the conversion-type-id be void? Who knows, but keep in mind it's not totally useless:

struct foo {     operator void()     {         std::cout << "huh?" << std::endl;     }  };  typedef void (foo::*void_function)();  foo f; void_function func = &foo::operator void;  (f.*func)(); // prints "huh" f.operator void(); // also does (which you knew) 

It is still technically potentially useful for something, so maybe that's rationale enough not to make it ill-formed.

like image 100
GManNickG Avatar answered Sep 22 '22 04:09

GManNickG