我有一种情况,我有许多字符串,我希望能够象征性地使用,即好像我宣布了一个宏
#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已经出局)。
答案 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"