3

在第 32 周的C++ Guru 中(谈到“合法”使用预处理器宏),最后一个示例显示了一个在DERR_ENTRY没有任何实际实现的情况下调用的宏:

DERR_ENTRY 和相关宏的实现留给读者。

这个宏应该替换这个:

 // For outsiders:
enum Errors {
  ERR_OK = 0,           // No error
  ERR_INVALID_PARAM = 1 // <description>
  ...
}

// For the module's internal use:
map<Error,const char*> lookup;
lookup.insert( make_pair( Error(0), "No error" ) );
lookup.insert( make_pair( Error(1), "<description>" ) );

有了这个:(更简单)

DERR_ENTRY( ERR_OK,            0, "No error" ),
DERR_ENTRY( ERR_INVALID_PARAM, 1, "<description>" ),
//...

根据 GotW 的作者:

我们希望在不定义实际信息(代码/消息对)两次的情况下同时拥有这两种表示形式。使用宏魔法,我们可以简单地编写如下错误列表,在编译时创建适当的结构

但是我看不到同时定义枚举条目和映射条目的简单方法。或者也许有未知的语法我不知道可以解决这个问题?

那么,您将如何实现 DERR_ENTRY 宏?

注意:请记住 GotW #32 应该说明预处理器宏的强大功能。

4

2 回答 2

3

作者可能指的是能够使宏在不同的地方具有不同的含义。在这种情况下,您可以执行以下操作:

InternalErrorDefinitions.h (此文件不应包含保护)。

DERR_ENTRY( ERR_OK,            0, "No error" )
DERR_ENTRY( ERR_INVALID_PARAM, 1, "<description>" )
...

Errors.h (这是模块的外部用户将包含的文件)

#define DERR_ENTRY(err, val, desc) err=val,
enum Errors {
#include "InternalErrorDefinitions.h"
};
#undef DERR_ENTRY

ModuleFile.cpp(模块的实现文件之一)

#define DERR_ENTRY(err, val, desc)  lookup.insert( make_pair( Error(val), desc ) );
map<Error,const char*> lookup;
#include "InternalErrorDefinitions.h"
#undef DERR_ENTRY

这允许您将错误定义仅放在一个位置,同时在使用它们的不同位置赋予它们不同的角色。

这种做法称为X-Macros。另请参阅Dobb 博士解释它们的这篇文章。

于 2012-09-03T13:22:57.657 回答
0
#define DERR_ENTRY(name, value, desc) \
    Error::DefineValue name(desc, value);

的实现Error::DefineValue留给读者。

于 2012-09-03T09:18:00.997 回答