Examples
Example 1: Overloading.
Say you have a Widget::Widget( unsigned int ) that can be invoked implicitly, and a Display function overloaded for Widgets and doubles. Consider the following overload resolution surprise:
void Display( double ); // displays a double
void Display( const Widget& ); // displays a Widget
Display( 5 ); // oops: creates and displays a Widget
Example 2: Errors that work.
Say you provide operator const char* for a String class:
class String {
// …
public:
operator const char*(); // deplorable form
};
Suddenly, a lot of silly expressions now compile. Assume s1, s2 are Strings:
int x = s1 - s2; // compiles; undefined behavior
const char* p = s1 - 5; // compiles; undefined behavior
p = s1 + '0'; // compiles; doesn't do what you'd expect
if( s1 == "0" ) { ...} // compiles; doesn't do what you'd expect
The standard string wisely avoids an operator const char* for exactly this reason.
|