Explicit conversion operators (C++11)

Note: IBM supports selected features of C++11, known as C++0x before its ratification. IBM will continue to develop and implement the features of this standard. The implementation of the language level is based on IBM's interpretation of the standard. Until IBM's implementation of all the C++11 features is complete, including the support of a new C++11 standard library, the implementation may change from release to release. IBM makes no attempt to maintain compatibility, in source, binary, or listings and other compiler interfaces, with earlier releases of IBM's implementation of the new C++11 features.

You can apply the explicit function specifier to the definition of a user-defined conversion function to inhibit unintended implicit conversions from being applied. Such conversion functions are called explicit conversion operators.

Read syntax diagramSkip visual syntax diagram
Explicit conversion operator syntax

>>-explicit--operator--conversion_type-------------------------->

>--+----------------------+--(--)--+----------+----------------->
   | .------------------. |        +-const----+   
   | V                  | |        '-volatile-'   
   '---pointer_operator-+-'                       

>--+---------------------+-------------------------------------><
   '-{--function_body--}-'   

The following example demonstrates both intended and unintended implicit conversions through a user-defined conversion function, which is not qualified with the explicit function specifier.

Example 1

#include <iostream>

template <class T> struct S {
  operator bool() const;   // conversion function
};

void func(S<int>& s) {
  
  // The compiler converts s to the bool type implicitly through
  // the conversion function. This conversion might be intended.
  if (s) { }
}

void bar(S<int>& p1, S<float>& p2) {
  // The compiler converts both p1 and p2 to the bool type implicitly
  // through the conversion function. This conversion might be unintended. 
  std::cout << p1+p2 << std::endl; 
  
  // The compiler converts both p1 and p2 to the bool type implicitly
  // through the conversion function and compares results. 
  // This conversion might be unintended. 
  if (p1==p2) { }  
}
To inhibit unintended implicit conversions from being applied, you can define an explicit conversion operator by qualifying the conversion function in Example 1 with the explicit function specifier:
explicit operator bool() const;
If you compile the same code as Example 1 but with the explicit conversion operator, the compiler issues error messages for the following statements:
// Error: The call does not match any parameter list for "operator+".
std::cout << p1+p2 << std::endl; 
 
// Error: The call does not match any parameter list for "operator==".
if(p1==p2)
If you intend to apply the conversion through the explicit conversion operator, you must call the explicit conversion operator explicitly as in the following statements, and then you can get the same results as Example 1.
std::cout << bool(p1)+bool(p2) << std::endl; 

if(bool(p1)==bool(p2))
In contexts where a Boolean value is expected, such as when &&, ||, or the conditional operator is used, or when the condition expression of an if statement is evaluated, an explicit bool conversion operator can be implicitly invoked. So when you compile Example 1 with the previous explicit conversion operator, the compiler also converts s in the func function to the bool type through the explicit bool conversion operator implicitly. Example 2 also demonstrates this:

Example 2

struct T {
  explicit operator bool();   //explicit bool conversion operator
};

int main() {
  T t1;
  bool t2;
  
  // The compiler converts t1 to the bool type through 
  // the explicit bool conversion operator implicitly.
  t1 && t2; 
 
  return 0;
}