设为首页 加入收藏

TOP

Item 2: Prefer consts, enums, and inlines to #defines.(4)
2013-10-07 14:25:32 来源: 作者: 【 】 浏览:50
Tags:Item Prefer consts enums and inlines #defines.

The enum hack is worth knowing about for several reasons. First, the enum hack behaves in some ways more like a #define than a const does, and sometimes that’s what you want. For example, it’s legal to take the address of a const, but it’s not legal to take the address of an enum, and it’s typically not legal to take the address of a #define, either. If you don’t want to let people get a pointer or reference to one of your integral constants, an enum is a good way to enforce that constraint. (For more on enforcing design constraints through coding decisions, consult Item 18.) Also, though good compilers won’t set aside storage for const objects of integral types (unless you create a pointer or reference to the object), sloppy compilers may, and you may not be willing to set aside memory for such objects. Like #defines, enums never result in that kind of unnecessary memory allocation.

A second reason to know about the enum hack is purely pragmatic. Lots of code employs it, so you need to recognize it when you see it. In fact, the enum hack is a fundamental technique of template metaprogramming (see Item 48).

Getting back to the preprocessor, another common (mis)use of the #define directive is using it to implement macros that look like functions but that don’t incur the overhead of a function call. Here’s a macro that calls some function f with the greater of the macro’s arguments:

  1. // call f with the maximum of a and b  
  2. #define CALL_WITH_MAX(a, b) f((a) > (b)   (a) : (b)) 

Macros like this have so many drawbacks, just thinking about them is painful.

Whenever you write this kind of macro, you have to remember to parenthesize all the arguments in the macro body. Otherwise you can run into trouble when somebody calls the macro with an expression. But even if you get that right, look at the weird things that can happen:

  1. int a = 5, b = 0;  
  2. CALL_WITH_MAX(++a, b);  // a is incremented twice  
  3. CALL_WITH_MAX(++a, b+10);  // a is incremented once 

max是永远的关于宏的反面案例。可悲的是,这里列出的template的解决方案也并非完美。有兴趣的同学可以在Google中搜索一篇题为min, max, and more的文章。那篇文章也正是本书作者Scott Meyers所写,你会惊叹把这么一件简单的事情做得完全正确是如此的困难。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Item 2: Prefer consts, enums, a.. 下一篇Item 2: Prefer consts, enums, a..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: