将字符串与变量连接并在C/C++中将其视为宏

Jam*_*Jam 0 c++ c++11

我试图弄清楚如何编写一个宏,将一个变量的值附加到字符串.这是一个非工作代码的片段,但我正在展示它,以便我可以解释我想要做什么

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

#define  DATA_RESPONCE_0 23
#define  DATA_RESPONCE_1 24
#define  DATA_RESPONCE_2 25
#define  DATA_RESPONCE_3 26

#define my_macro(x) DATA_RESPONCE_##x


int main() {

    int i = 0;
    int k;

    k = my_macro (i);

    cout << k;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,宏被扩展为DATA_RESPONCE_i,但我希望它是DATA_RESPONCE_0,因此23应该打印为k的值.

Sto*_*ica 5

你不能用宏来做.预处理(扩展宏时)是编译的第一步.早在i可能知道的价值之前.

如果您打算将运行时值映射到某个值,请使用正确的函数:

int my_function(int x)
{
  static const int map[] = {
    DATA_RESPONCE_0,
    DATA_RESPONCE_1,
    DATA_RESPONCE_2,
    DATA_RESPONCE_3
  };

  assert (x >= 0 && x < sizeof(map)/sizeof(map[0]));
  return map[x];
}
Run Code Online (Sandbox Code Playgroud)

我使用了assert宏,因为当你x不是一个有效的值时你似乎想要硬故障.


关于一个密切相关的话题.除非您的宏位于C和C++代码所包含的标题中,否则更喜欢定义常量的C++样式:

enum class data_response { // Properly scoped. 
  type_0 = 23,
  type_1, // Consecutive values are used after 23. No need to specify 24
  type_2,
  type_3
};
Run Code Online (Sandbox Code Playgroud)

适当范围enum class将降低对全局命名空间的污染量.甚至可以进一步命名空间.它优于不能尊重名称空间或作用域的宏.

data_response my_function(int x)
{
  static const data_response map[] = {
    data_response::type_0,
    data_response::type_1,
    data_response::type_2,
    data_response::type_3
  };

  assert (x >= 0 && x < sizeof(map)/sizeof(map[0]));
  return map[x];
}
Run Code Online (Sandbox Code Playgroud)