Item 45. BOOL

Item 45. BOOL

Difficulty: 7

Do we really need a builtin bool type? Why not just emulate it in the existing language? This Item reveals the answer.

Besides wchar_t (which was a typedef in C), bool is the only builtin type to be added to C++ since the ARM (Ellis90).

Could bool's effect have been duplicated without adding a builtin type? If yes, show an equivalent implementation. If no, show why possible implementations do not behave the same as the builtin bool.

 

Solution

graphics/bulb_icon.gif

The answer is: No, bool's effect could not have been duplicated without adding a builtin type. The bool builtin type, and the reserved keywords true and false, were added to C++ precisely because they couldn't be duplicated completely using the existing language.

This Item is intended to illustrate the considerations you have to think about when you design your own classes, enums, and other tools.

The second part of the Item question was: If no, show why possible implementations do not behave the same as the builtin bool.

There are four major implementations.

Option 1: typedef (score: 8.5 / 10)

This option means to "typedef <something> bool;", typically:

// Option 1: typedef 
//
typedef int bool;
const bool true  = 1;
const bool false = 0;

This solution isn't bad, but it doesn't allow overloading on bool. For example:

// file f.h 
void f( int  ); // ok
void f( bool ); // ok, redeclares the same function
// file f.cpp
void f( int  ) { /*...*/ }  // ok
void f( bool ) { /*...*/ }  // error, redefinition

Another problem is that Option 1 can allow code like this to behave unexpectedly:

void f( bool b ) 
{
  assert( b != true && b != false );
  }

So Option 1 isn't good enough.

Option 2: #define (score: 0 / 10)

This option means to "#define bool <something>", typically:

// Option 2: #define 
//
#define bool  int
#define true  1
#define false 0

This is, of course, purely evil. It not only has all the same problems as Option 1, but it also wreaks the usual havoc of #defines. For example, pity the poor customer who tries to use this library and already has a variable named false; now this definitely behaves differently from a builtin type.

Trying to use the preprocessor to simulate a type is just a bad idea.

Option 3: enum (score: 9 / 10)

This option means to make an "enum bool", typically:

// Option 3: enum 
//
enum bool { false, true };

This is somewhat better than Option 1. It allows overloading (the main problem with the first option), but it doesn't allow automatic conversions from a conditional expression (which would have been possible with the first option), to wit:

bool b; 
b = ( i == j );

This doesn't work, because ints cannot be implicitly converted to enums.

Option 4: Class (score: 9 / 10)

Hey, this is an object-oriented language, right? So why not write a class, typically:

class bool 
{
public:
  bool();
  bool( int );            // to enable conversions from
  bool& operator=( int ); //  conditional expressions
  //operator int();   // questionable!
  //operator void*(); // questionable!
private:
  unsigned char b_;
};
const bool true ( 1 );
const bool false( 0 );

This works except for the conversion operators marked "questionable." They're questionable because:

  • With an automatic conversion, bools will interfere with overload resolution, just as do all classes having non-explicit (conversion) constructors and/or implicit conversion operators, especially when the conversion is from or to a common type. See Items 20 and 39 for more about implicit conversions.

  • Without a conversion to something like int or void*, bool objects can't be tested "naturally" in conditions. For example:

    bool b; 
    /*...*/
    if( b ) // error without an automatic conversion to
    {       // something like int or void*
        /*...*/
    }
    

It's a classic Catch-22 situation: We must choose one alternative or the other梕ither provide an automatic conversion or not梑ut neither option lets us duplicate the effect of having a builtin bool type. In summary:

  • A typedef ... bool wouldn't allow overloading on bool.

  • A #define bool wouldn't allow overloading either and would wreak the usual havoc of #defines.

  • An enum bool would allow overloading but couldn't be automatically converted from a conditional expression (as in "b = (i == j);").

  • A class bool would allow overloading but wouldn't let a bool object be tested in conditions (as in "if( b )") unless it provided an automatic conversion to something like int or void*, which would wreak the usual havoc of automatic conversions.

And, finally, there's one more thing (related to overloading) that we couldn't have done otherwise, either, except perhaps with the last option: Specify that conditional expressions have type bool.

So, yes, we really did need a builtin bool.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值