advertisement
Login | Register   
  Include Code  Search Tips
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
The technique presented here addresses the specific case of Boolean conversions. Recently, the C++ standards committee accepted a proposal to add explicit conversion operators to C++. Do you believe that this proposal is the right solution to the problem? What about conditional declarations? Let us know in the DevX C++ Forum.
Partners & Affiliates
advertisement
advertisement
advertisement
advertisement
Average Rating: 5/5 | Rate this item | 4 users have rated this item.
Restrain Conversion Operators with the "Indirect Conversion" Idiom (cont'd)
Smooth Operator
Let's analyze the return statement. If rawptr isn't NULL, the conversion operator returns a pointer to a member of struct PtrConversion (the precise value of the expression &PtrConversion::valid is immaterial; what matters is that it's a non-NULL constant). However, if rawptr is NULL, the conversion operator returns a NULL pmi. Recall that all pointers to members are implicitly convertible to bool; they aren't bool variables, though. This subtle difference is crucial, as you will see.
advertisement

After this change, when the following statement executes:


if(ptr)
//...
C++ calls ptr.operator pmi() behind the scenes. The return value of type pmi is then silently converted to bool, as expected. However, the following statement no longer compiles, which is exactly what you want:

cout<<"p1 + p2 = "<< p1+p2 <<endl; //compilation error
Here's the secret: C++ guarantees that an operand shall undergo at most one implicit conversion. In the if(ptr) example, you have exactly one implicit conversion from pmi to bool (the very invocation of a conversion operator doesn't constitute an implicit conversion for this matter). However, in the expression p1+p2 two implicit conversions per operand are necessary:
  1. pmi—>bool
  2. bool—>int
As I said, C++ doesn't allow this.

Let's see how this technique eliminates the problems caused by a void* conversion operator:


cout << pf <<endl; //now a compilation error
This statement no longer compiles since there is no overloaded version of operator << that takes pmi or Ptr<T>. Similarly, the following delete expression:

delete pf; //compilation error
doesn't compile because neither pmi nor bool are valid types in a delete expression.

Twisting by the bool
The boost::shared_ptr class uses a slightly different version of the indirect conversion technique. Instead of using a dummy nested struct, it uses a pointer to a member of class shared_ptr itself. In terms of memory footprint, there is no difference between the two versions because the dummy struct is not instantiated anyway. However, some compilers have difficulties coping with pointers to member functions of a class template so the Boost library uses conditional compilation to switch between a pointer to a data member and a pointer to a member function as the target type of the Boolean conversion operator. The bottom line is this: instead of bool, void* or int as the target type of a Boolean conversion operator, use a pointer to member to minimize the perils of implicit conversions.

Previous Page: booling Around  
Danny Kalev is a certified system analyst and software engineer specializing in C++ and the theoretical aspects of formal languages. He is the author of Informit C++ Reference Guide and The ANSI/ISO Professional C++ Programmer's Handbook. He was a member of the C++ standards committee between 1997 and 2000. Danny recently finished his MA in general linguistics summa cum laude. In his spare time he likes to listen to classical music, read Victorian literature, and explore natural languages such as Hittite, Basque, and Irish Gaelic. Additional interests include archeology and geology. He also gives lectures about programming languages and applied linguistics at academic institutes.
Page 1: IntroductionPage 3: booling Around
Page 2: Presenting the ProblemPage 4: Smooth Operator
Please rate this item (5=best)
 1  2  3  4  5
advertisement