编写预处理程序指令以获取字符串

时间:2010-03-11 05:47:20

标签: c++ c-preprocessor

您是否可以编写预处理程序指令来返回std :: string或char *?

例如:如果是整数:

#define square(x) (x*x)

int main()
{
   int x = square(5);
}

我希望做同样的事情但是使用像开关盒模式这样的字符串。如果传递1,它应该返回“一个”,2个返回“两个”,所以...

4 个答案:

答案 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