Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX



Use Explicit Conversion Functions to Avert Reckless Implicit Conversions -2 : Page 2

Conversion functions are inherently unsafe as they might surprise you with implicit conversions over which you have no control. This is why such functions have been avoided for years. Learn how the new C++0x explicit conversion functions put an end to years of conversion functions blues.





Ambiguity Issues
Suppose you're designing a simple string class. Naturally, your class defines a conversion functions to char * and an overloaded [] operator. Each of these functions has a const and a non-constversion:

class BuggyString {
 char buf[100];
 BuggyString(const char* s);
 char& operator[] (size_t n);
 const char& operator[] (size_t n) const;

//implicit conversion to char*
 operator char* ();
 operator const char* () const;

When some compilers compile the following code, they issue a compilation error:

BuggyString str("buggi");
str[4] = 'y'; //error, overload resolution ambiguity

Where does this error come from? When the compiler sees the expression str[4], it looks up the definition of str and discovers that str isn't an array. At this stage, there are two possible ways to interpret the expression str[4]:

  • Invoking the overloaded [] member function.
  • Invoking BuggyString::operator char *, and then applying the built-in [] operator to the result.

In other words, depending on the underlying type of std::ptrdiff_t (which affects overload resolution) the compiler is faced with two options: either interpret str[4]as:

str.operator[](4) //call overloaded []

or interpret it as:

str.operator char*()[4]//call operator char* +built-in []

In C++03, the common approach is to avoid conversion functions in the first place. The std::string class, for example, defines the member function string::c_str() as a substitute for operator const char *. This approach works well when the destination type is known at compile time. However, when templates are involved, named functions are problematic because the destination type can only be determined when you instantiate a template.

Comment and Contribute








