Previous section   Next section

Imperfect C++ Practical Solutions for Real-Life Programming
By Matthew Wilson
Table of Contents
Chapter 24.  operator bool()


24.8. operator!

We've seen how to implement operator "Boolean"() and relied on the fact that the compiler can apply a logical negation to an instance supporting our operator "Boolean"().



ExpressibleThing  e;





if(!e) // Negates operator boolean_type::return_type() const


{}



With both the T const *() and the int T::*() forms, all compilers tested are able to apply negation, so there is no need to explicitly provide operator !() in addition to our operator "Boolean"().

However, there are times when this is too coarse grained. A good example is when dealing with database types, such as VARCHAR, which can, like many string class implementations, have more than two-states: null, empty, and nonempty. Essentially, for VARCHAR, and for string classes, the logical negation—whether it is implicitly done by the compiler or via an operator !() const method—does not have enough information. Since it is useful with such types to be able to test against these multiple states, we need to find a mechanism to do so. Naturally we must use methods:



class varchar_field


{


public:


  bool is_empty() const;


  bool is_null() const;


};



But then we run up against a lack of genericity. If we want to use the code that is testing the database fields for something else, the is_null() or is_empty() methods may not be available. The answer here, of course, is to rely on our old friends the Attribute Shims (section 20.2). Hence,



bool is_null(varchar_field const &);


bool is_empty(varchar_field const &);


bool is_not(varchar_field const &);



The advantage to this is that we are not forced to make a preemptive, and irreversible, decision by binding the meaning of "is" or "is not" in the type, but can delay it until appropriate, in the client code. The disadvantage is that it makes the client code less succinct—although I'd argue it is more readable—and we have to take care to maintain consistency to avoid ending up with a large number of shims, leading to confusion on the part of the authors and maintainers of code.


      Previous section   Next section