在 C++11 中,无法在编译时将临时字符串存储在任何地方。所以我可以建议你这种方法:(这是快速制作的草图,但描述性很好)
#include <stdio.h>
template <char...>
struct StringTuple;
template <char TargHead>
struct StringTuple<TargHead> {
static constexpr char kSymbol = TargHead;
static void print() {
printf(kSymbol ? "%c\n" : "\n", kSymbol);
}
};
template <char TargHead, char... TargTail>
struct StringTuple<TargHead, TargTail...> {
using Next = StringTuple<TargTail...>;
static constexpr char kSymbol = TargHead;
static void print() {
if (kSymbol) {
printf("%c", kSymbol);
Next::print();
} else {
printf("\n");
}
}
};
constexpr int length(char *string) {
return (string[0] == 0) ? 1 : (length(string + 1) + 1);
}
constexpr char get(char *string, int i) {
return i < length(string) ? string[i] : 0;
}
#define ST(string) \
StringTuple< \
get(string, 0), \
get(string, 1), \
get(string, 2), \
get(string, 3), \
get(string, 4), \
get(string, 5), \
get(string, 6), \
get(string, 7), \
get(string, 8), \
get(string, 9), \
get(string, 10), \
get(string, 11), \
get(string, 12), \
get(string, 13), \
get(string, 14), \
get(string, 15), \
get(string, 16), \
get(string, 17), \
get(string, 18), \
get(string, 19), \
get(string, 20), \
get(string, 21), \
get(string, 22), \
get(string, 23), \
get(string, 24), \
get(string, 25), \
get(string, 26), \
get(string, 27), \
get(string, 28), \
get(string, 29), \
get(string, 30), \
get(string, 31), \
get(string, 32), \
get(string, 33), \
get(string, 34), \
get(string, 35), \
get(string, 36), \
get(string, 37), \
get(string, 38), \
get(string, 39), \
get(string, 40), \
get(string, 41), \
get(string, 42) \
>
int main() {
ST("Hello, compile-time world!")::print();
}
生成部分宏的 Bash 代码:
for i in `seq 0 42`; do echo " get(string, $i), \\"; done
您必须将大量(1000 或更多)传递给此生成器以支持所有字符串,并且如果字符串超过此限制,您必须进行静态断言。
我在自己的科学项目中使用这种生成的宏。我知道这看起来很乱,但它确实有效。生成宏的使用示例:
#define PRINT(a) print(a);
FOREACH_MACRO(PRINT, a, b, c) // print(a);print(b);print(c);
我会尝试找到更漂亮的解决方案,但首先我会使用它。