[更新:2018.05.03]
CAVEAT:并非所有编译器都以相同的方式实现C ++ 11规范。下面的代码在我测试的编译器中工作,而许多评论者使用不同的编译器。
引自Shafik Yaghmour的回答:在编译时计算C字符串的长度。 这真的是一个constexpr吗?
不保证在编译时计算常量表达式 时间,我们只有草案C ++标准的非规范性引用 5.19节这样说的常量表达式:
[...]> [注意:可以在期间评估常量表达式 翻译 - 结束说明]
can这个词在全世界都有所不同。
所以,YMMV对此(或任何)答案涉及USER,具体取决于编译器编写者对规范的解释。
[更新2016.01.31]
由于有些人不喜欢我之前的回答,因为它通过完成目标而不需要字符串比较来避免OP的整个方面,这里有一个更详细的答案。
你不能! 不在C98或C99中。 甚至没有在C11。 没有多少MACRO操作会改变这一点。
USER中使用的USER的定义不允许使用字符串。
它允许使用字符,因此如果您将自己限制为字符,则可以使用此字符:
#define JACK 'J'
#define QUEEN 'Q'
#define CHOICE JACK // or QUEEN, your choice
#if 'J' == CHOICE
#define USER "jack"
#define USER_VS "queen"
#elif 'Q' == CHOICE
#define USER "queen"
#define USER_VS "jack"
#else
#define USER "anonymous1"
#define USER_VS "anonymous2"
#endif
#pragma message "USER IS " USER
#pragma message "USER_VS IS " USER_VS
您可以! 在C ++ 11中。 如果为比较定义编译时辅助函数。
// compares two strings in compile time constant fashion
constexpr int c_strcmp( char const* lhs, char const* rhs )
{
return (('\0' == lhs[0]) && ('\0' == rhs[0])) ? 0
: (lhs[0] != rhs[0]) ? (lhs[0] - rhs[0])
: c_strcmp( lhs+1, rhs+1 );
}
// some compilers may require ((int)lhs[0] - (int)rhs[0])
#define JACK "jack"
#define QUEEN "queen"
#define USER JACK // or QUEEN, your choice
#if 0 == c_strcmp( USER, JACK )
#define USER_VS QUEEN
#elif 0 == c_strcmp( USER, QUEEN )
#define USER_VS JACK
#else
#define USER_VS "unknown"
#endif
#pragma message "USER IS " USER
#pragma message "USER_VS IS " USER_VS
因此,最终,您必须改变您实现选择USER和queen的最终字符串值的目标的方式。
您不能在C99中进行编译时字符串比较,但您可以选择字符串进行编译时。
如果您真的必须进行编译时间比较,那么您需要更改为允许该功能的C ++ 11或更新版本。
[原始回答]
尝试:
#define jack_VS queen
#define queen_VS jack
#define USER jack // jack or queen, your choice
#define USER_VS USER##_VS // jack_VS or queen_VS
// stringify usage: S(USER) or S(USER_VS) when you need the string form.
#define S(U) S_(U)
#define S_(U) #U
更新:ANSI令牌粘贴有时不太明显。;-D
在宏之前放置一个USER会导致它被更改为其值的字符串,而不是其裸值。
在两个令牌之间放置一个双重USER会使它们连接成一个令牌。
所以,宏USER有扩展queen或"jack",具体取决于你如何设置S_(jack_VS)。
stringify宏USER使用宏间接,因此命名宏的值将转换为字符串。 而不是宏的名称。
因此USER变为queen(或"jack"),具体取决于您如何设置S_(jack_VS)。
稍后,当stringify宏用作USER时,将值queen(在该示例中为"jack")传递给间接步骤S_(jack_VS),其将其值(queen)转换为字符串"queen"。
如果将USER设置为queen,则最终结果为字符串"jack"。
有关标记连接,请参阅:[https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html]
有关令牌字符串转换,请参阅:[https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification]
[更新2015.02.15纠正错字。]