定义具有相同名称和值的符号字符串常量

时间:2013-04-24 15:35:25

标签: c++ c-preprocessor

我有一种情况,我有许多字符串,我希望能够象征性地使用,即好像我宣布了一个宏

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

我有多种原因无法使用枚举(更多上下文请参阅此previous question),例如在调试器中获取有用信息,以可读格式序列化数据以及处理定义的属性集在不同的源文件中。

典型用法:

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(所以in-class constant initialisers已经出局)。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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"