0

我有一种情况,我有一些我希望能够以符号方式使用的字符串,即好像我声明了一个宏

#define kBlahProperty "kBlahProperty"
#define kFooProperty "kFooProperty"

我不能使用枚举的原因有很多(有关更多上下文,请参阅上一个问题),例如在调试器中获取有用的信息、以可读格式序列化数据以及处理不同源文件中定义的属性集。

典型用法:

setProperty(kBlahProperty, 6);
if (otherProperty==kBlahProperty) { doStuff(); }
std::cout << "property type: " << kBlahProperty;  // outputs "kBlahProperty" rather than an enum

这些属性可能有很多,为了简化定义,我希望能够像这样声明它们,只在一个地方:

DEFINE_PROPERTY(kBlahProperty)
DEFINE_PROPERTY(kFooProperty)

但是,我找不到一种方法来定义一个本身会扩展为 #define 的宏(我已经尝试了几个带有 '#' 和 '##' 运算符的示例,但是要粘贴 '#define'是问题)。

另一种方法是将要扩展的宏定义为char*

#define DEFINE_PROPERTY(propName) const char8* propName=#propName

但这有一个问题,即它在每个编译单元中都被定义,因此链接器错误。如果我将其更改为使用,extern那么我无法将其定义为使用字符串本身——它必须放在 .cpp 文件中,所以现在我需要在标头中声明所有这些属性并在 cpp 中再次定义它们文件,因此您在两个地方都有一个列表。

那么有没有一种定义这些字符串的好方法,以便您可以只声明它们一次?我可以访问 boost 预处理器,但只能访问 C++-0x 的一小部分(因此类内常量初始化器已被淘汰)。

4

2 回答 2

2

您可以将宏定义为 have 和 #ifdef,使其具有两条路径 - if 和 else。然后在标题中它只是声明你的propName。然后在您的 .cpp 文件中,在包含标头之前定义一个预处理器变量。该定义将使您的宏定义propName。

于 2013-04-24T15:44:55.213 回答
2

简单(如果丑陋)的方式 - 仅在未定义另一个符号时定义宏以包含 extern,并在包含标头之前在一个编译单元中定义该符号

举例(包括为清楚起见省略的警卫)

#ifdef IN_CPP
#define DEFINE_PROPERTY(propName) const char8* propName=#propName;
#else
#define DEFINE_PROPERTY(propName) extern const char8* propName;
#endif

在一个编译单元中:

#define IN_CPP 1
#include "header.h"

在剩余的编译单元中:

#include "header.h"
于 2013-04-24T16:07:30.247 回答