您是否可以编写预处理程序指令来返回std :: string或char *?
例如:如果是整数:
#define square(x) (x*x)
int main()
{
int x = square(5);
}
我希望做同样的事情但是使用像开关盒模式这样的字符串。如果传递1,它应该返回“一个”,2个返回“两个”,所以...
答案 0 :(得分:2)
您不希望在C ++中使用宏来执行此操作;功能很好:
char const* num_name(int n, char const* default_=0) {
// you could change the default_ to something else if desired
static char const* names[] = {"Zero", "One", "Two", "..."};
if (0 <= n && n < (sizeof names / sizeof *names)) {
return names[n];
}
return default_;
}
int main() {
cout << num_name(42, "Many") << '\n';
char const* name = num_name(35);
if (!name) { // using the null pointer default_ value as I have above
// name not defined, handle however you like
}
return 0;
}
同样, square 应该是一个函数:
inline int square(int n) {
return n * n;
}
(虽然在实践中 square 不是很有用,但你只是直接乘法。)
作为一个好奇心,虽然我不建议在这种情况下(上面的功能很好),模板元编程的等价物将是:
template<unsigned N> // could also be int if desired
struct NumName {
static char const* name(char const* default_=0) { return default_; }
};
#define G(NUM,NAME) \
template<> struct NumName<NUM> { \
static char const* name(char const* default_=0) { return NAME; } \
};
G(0,"Zero")
G(1,"One")
G(2,"Two")
G(3,"Three")
// ...
#undef G
请注意,TMP示例失败的主要方式是您必须使用编译时常量而不是任何int。
答案 1 :(得分:1)
#define
预处理程序指令会替换源代码中的字符串。您想要的case...when
构造仍然不是微不足道的:
#define x(i) ((i)==1?"One":((i)==2?"Two":"Many"))
可能是一个开始 - 但定义类似
的东西static char* xsof[] = ["One", "Two", "Many"];
和
#define x(i) xsof[max(0, min((i)-1, (sizeof xsof / sizeof xsof[0] - 1)))]
似乎更合理,表现更好。
编辑:根据Chris Lutz的建议,使第二个宏自动调整为xsof
定义;根据马克的说法,将计数作为基础1。
答案 2 :(得分:1)
我见过这个......
#define STRING_1() "ONE"
#define STRING_2() "TWO"
#define STRING_3() "THREE"
...
#define STRING_A_NUMBER_I(n) STRING_##n()
#define STRING_A_NUMBER(n) STRING_A_NUMBER_I(n)
我相信这个额外的步骤是确保n被评估,所以如果你传递1 + 2,它会在传递给STRING_A_NUMBER_I之前变为3,这似乎有点躲闪,任何人都可以详细说明吗?
答案 3 :(得分:0)
你不能将整数转换成字符串,所以1 ---&gt; “一个”,2 ---&gt; “两个”等,除了枚举每个值。
您可以使用C预处理器将参数值转换为字符串:
#define STRINGIZER(x) #x
#define EVALUATOR(x) STRINGIZER(x)
#define NAME(x) EVALUATOR(x)
NAME(123) // "123"
#define N 123
#define M 234
NAME(N+M) // "123+234"
另见SO 1489932。