我有一个宏来将一个字符串转换为一个字符列表:
#define TO_STRING(x) #x
#define CHAR_LIST_7(x) TO_STRING(x)[0] \
, TO_STRING(x)[1] \
, TO_STRING(x)[2] \
, TO_STRING(x)[3] \
, TO_STRING(x)[4] \
, TO_STRING(x)[5] \
, TO_STRING(x)[6]例如,用法:“CHAR_LIST_7(鸡)”表示"'c','h','i','c','k','e','n'“,所以它可以用在模板中(例如:http://hpaste.org/47313/exand )
但是,我想将其推广到任意数量的字符(而不需要手动计算字符数)?所以我可以简单地说:CHAR_LIST(任意文本)。有什么想法或解决方案吗?
发布于 2011-08-08 12:52:26
你不能在预处理过程中拆分令牌,只能组合它们(使用##)。
将标识符转换为字符串文字也没有帮助,因为您不能在预处理过程中将字符串文字拆分开,也不能对字符串文字执行操作(例如计算长度)。
在预处理期间,编译器知道标记是字符串文字以及它是哪种文字,但它还不知道它的完整类型和长度,至少不知道宏可以访问的方式。
发布于 2011-08-08 14:16:49
你要求拆分的方式在一般形式下是不可能的。最好的方法是将参数原样提供给template
Literal<'c','h','i','c','k','e','n'>::print();我知道这需要更多的打字。为了克服这个问题,你可以编写一个简单的程序,它接受一个像chicken这样的字符串作为参数,并将它输出到'c','h','i',...etc中。类似于:
int main(int argc, char **argv)
{
if(argc != 2)
return 0;
const char *s = argv[1];
int length = strlen(s)-1;
for(int i = 0; i < length; i++)
cout<<s[i]<<",";
cout<<s[length]<<endl;
}但是,由于template参数中包含拆分字符,因此没有解决冗长问题的解决方案。
发布于 2011-08-08 14:50:32
不,正如James已经说过的,没有办法在预处理器中拆分标记,或者让它知道字符串的长度。
但我认为,对于您的用例,这在任何情况下都是没有必要的。通过使用#x将参数字符串化得到的字符串是一个固定大小的字符串,例如,chicken通向"chicken",它只有char[8]类型。这样字符串的长度是一个编译时间常数,您可以使用sizeof简单地检测它
#define TOKLEN(TOK) (sizeof(#TOK)-1)在C中使用这样的东西看起来“很简单”
#define SCARY(TOK) for (size_t i = 0; i < TOKLEN(TOK); ++i) printf("%c:", #TOK[i])因为TOKLEN(TOK)是一个编译时间常量,所以如果合适的话,编译器可以展开它。
在您的C++用例中使用它
template < size_t n >
class constLenString {
size_t const len = n;
char const* str;
constLenString(char* s) : str(s) { }
};
#define defConstLenString(TOK, NAME) constLenString< TOKLEN(TOK) > NAME(#TOK)(未经测试,我的C++已生锈)
现在有了
defConstLenString(chicken, chick);chick.n是一个常量,它可以是for循环或其他任何东西的界限,编译器应该能够完美地优化一切。
https://stackoverflow.com/questions/6977847
复制相似问题