Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在本周大师32中实现DERR#u ENTRY宏? C++中(关于预处理器宏的合法使用),最后一个例子显示了一个宏,称为“代码> DrryAccess < /Cord>”,没有任何实际的实现:_C++ - Fatal编程技术网

如何在本周大师32中实现DERR#u ENTRY宏? C++中(关于预处理器宏的合法使用),最后一个例子显示了一个宏,称为“代码> DrryAccess < /Cord>”,没有任何实际的实现:

如何在本周大师32中实现DERR#u ENTRY宏? C++中(关于预处理器宏的合法使用),最后一个例子显示了一个宏,称为“代码> DrryAccess < /Cord>”,没有任何实际的实现:,c++,C++,DERR_条目和相关宏的实现留给读者 此宏应替换以下内容: // 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

DERR_条目和相关宏的实现留给读者

此宏应替换以下内容:

 // 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>" ) );
//对于外部人员:
枚举错误{
ERR_OK=0,//无错误
错误\u无效\u参数=1//
...
}
//对于模块的内部使用:
地图查找;
查找.插入(生成配对(错误(0),“无错误”);
查找.插入(生成配对(错误(1),“”);
有了这个:(简单多了)

DERR_条目(ERR_OK,0,“无错误”),
DERR_条目(ERR_无效参数,1,“”),
//...
根据GotW的作者:

我们希望两种表示都不需要定义实际信息(代码/消息对)两次。使用宏魔术,我们可以简单地编写如下错误列表,在编译时创建适当的结构

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

那么,如何实现DERR_ENTRY宏呢

注意:记住GotW#32是用来说明预处理器宏的功能的

#define DERR_ENTRY(name, value, desc) \
    Error::DefineValue name(desc, value);

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

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

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

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

#定义DERR_项(err,val,desc)查找。插入(make_对(Error(val),desc));
地图查找;
#包括“InternalErrorDefinitions.h”
#未定义DERR_条目
这允许您只在一个地方拥有错误定义,同时在使用它们的不同地方赋予它们不同的角色


这种做法被称为。另请参见解释。

@Offirmo好的,还有一个提示<代码>类型定义枚举类型错误如何在枚举中动态插入新值???这是我从没听说过的事,你不必这么做。您只需创建一个实例与枚举值类似的类。(请参见宏中的
name
)啊。。是的,当然,如果我们放弃约束以使用枚举表示,那么就很容易了。但是,这不是在逃避gw32中给出的问题吗?重点是用更好的东西替换糟糕的代码。有趣的是。。。看起来与GotW32中的示例不一样,但仍然很有趣。@Offirmo:为什么您说它与GotW32中的示例不一样?GotW说“将这个(上面没有给出宏的代码)替换为那个(上面给出了带有DERR_项的代码)”。您的版本有一个相当复杂的替换代码,其中包含#define and#include。当然,我们可以解释GotW32中所说的(替换…)。@Offirmo:我不明白你的逻辑。如果GotW要求替换代码,而我的代码是替换代码,那么有什么问题?我的代码完全按照GotW的要求执行,是一个很好的例子。如果您需要像原始代码中那样创建枚举,您将找不到更好的解决方案。是的,它有点复杂,但是如果它很简单,那么它将在GotW文章中给出,而不是留给读者。@Offirmo:但是需要#define来实现宏是很常见的,这正是这里需要的。我觉得你要么误解了GotW专栏,要么误解了我的答案,但我不知道是哪个。有人读过《更卓越的C++》这本书吗。GotW#32页上说,“书中的解决方案自最初出现在GotW以来已被修订和扩展。书中的版本还包含更正……”。那么,答案可能就在书中?好吧,在阅读了当前的答案并与一些同事交谈之后,我们都同意,只要我们具有类型安全性和切换…情况的能力,我们就可以用任何其他类型替换enum。解决方案仍然是受欢迎的!
#define DERR_ENTRY(name, value, desc) \
    Error::DefineValue name(desc, value);
DERR_ENTRY( ERR_OK,            0, "No error" )
DERR_ENTRY( ERR_INVALID_PARAM, 1, "<description>" )
...
#define DERR_ENTRY(err, val, desc) err=val,
enum Errors {
#include "InternalErrorDefinitions.h"
};
#undef DERR_ENTRY
#define DERR_ENTRY(err, val, desc)  lookup.insert( make_pair( Error(val), desc ) );
map<Error,const char*> lookup;
#include "InternalErrorDefinitions.h"
#undef DERR_ENTRY