Discussion
Team LiB
Previous Section Next Section

Discussion

If you're in the office and run out of paper, what do you do? Of course, you walk to your trusty photocopier and make several copies of a white sheet of paper.

As silly as it sounds, this is often what implicit conversions do: unnecessarily go through the trouble of creating temporaries, just to perform some trivial operation on them and toss them away (see Item 40). A common example is string comparison:



class String {// …


  String( const char* text );                    // enables implicit conversion


};


bool operator==( const String&, const String& );


// … somewhere in the code …


if( someString == "Hello" ) {... }



Having seen the definitions above, the compiler will compile the comparison as if you had written s == String("Hello"). This can be quite wasteful, considering that you don't need to copy the characters just to read them. The solution to this problem is simple: define overloads that avoid the conversion. For example:



bool operator==( const String& lhs, const String& rhs );     // #1


bool operator==( const String& lhs, const char* rhs );       // #2


bool operator==( const char* lhs, const String& rhs );       // #3



That looks like a lot of code duplication, but in reality it is only "signature duplication" because all three typically use the same back-end function. You're unlikely to commit a premature optimization heresy (see Item 8) with such simple overloads, and it's de bon goût to provide them especially when designing a library when it's difficult to predict in advance what common types will be in performance-sensitive code.

    Team LiB
    Previous Section Next Section