【问题标题】:Macro string concatenation宏字符串连接
【发布时间】:2014-05-31 09:50:36
【问题描述】:

我使用宏来连接字符串,例如:

#define STR1 "first"
#define STR2 "second"

#define STRCAT(A, B) A B

拥有STRCAT(STR1 , STR2 ) 会产生"firstsecond"

我在其他地方以这种方式将字符串关联到枚举:

enum class MyEnum
{
    Value1,
    Value2
}
const char* MyEnumString[] =
{
    "Value1String",
    "Value2String"
}

现在以下方法不起作用:

STRCAT(STR1, MyEnumString[(int)MyEnum::Value1])

我只是想知道是否可以构建一个将#defined 字符串文字与const char* 连接起来的宏?否则,我想我会不用宏,例如以这种方式(但也许你有更好的方式):

std::string s = std::string(STR1) + MyEnumString[(int)MyEnum::Value1];

【问题讨论】:

  • 你为什么这么想用宏?你知道他们在 C++ 中被强烈劝阻吗?
  • @tenfour 我真的不知道(因为我不是 C++ 专家)。所以你会建议避免使用 STRCAT(STR1, STR2) 宏?您能否详细说明使用它的缺点是什么?
  • 查看这里以获得好的答案:stackoverflow.com/a/14041847/402169。但对我来说,更好的问题是:既然可以使用函数,为什么还要使用宏?
  • 感谢您的链接。好吧,在我的情况下,我确保我的宏不能与其他名称冲突(宏名称带有前缀),并且我只将它们用于字符串,它为我的 IO dll 中的变量提供名称,该名称也被其他用户使用。如您所说,另一种选择可能是提供返回变量名称的函数,也许是通过将枚举作为输入。我会考虑是否值得切换到这个解决方案。

标签: c++ macros c-preprocessor string-concatenation


【解决方案1】:

该宏仅适用于字符串文字,即用双引号括起来的字符序列。宏起作用的原因是 C++ 标准将相邻的字符串文字视为单个字符串文字。换句话说,如果你写,编译器没有区别

"Quick" "Brown" "Fox"

"QuickBrownFox"

连接是在编译时执行的,在您的程序开始运行之前。

const char* 变量的串联需要在运行时发生,因为字符指针(或任何其他指针,就此而言)直到运行时才存在。这就是为什么你不能用你的 CONCAT 宏来做到这一点。不过,您可以使用 std::string 进行连接 - 这是解决此问题的最简单方法之一。

【讨论】:

    【解决方案2】:

    仅适用于char 文字,它们可以以这种方式连接:

     "A" "B"
    

    这不适用于示例中的指针表达式,它会扩展为类似

    的语句
     "STR1" MyEnumString[(int)MyEnum::Value1];
    

    至于您的编辑:
    是的,我肯定会接受你的建议

     std::string s = std::string(STR1) + MyEnumString[(int)MyEnum::Value1];
    

    【讨论】:

      【解决方案3】:

      您的宏是非常不必要的,因为它只能与相同类型的字符串文字一起使用。在功能上它什么都不做。

      std::string s = STRCAT("a", "b");
      

      完全一样:

      std::string s = "a" "b";
      

      所以我觉得最好不要使用宏。如果你想要一个运行时字符串连接函数,一个更 C++ 规范的版本是:

      inline std::string string_concat(const std::string& a, const std::string& b)
      {
          return a + b;
      }
      

      但是,当你能做到的时候,拥有这个功能似乎几乎毫无意义:

      std::string a = "a string";
      std::string ab = a + "b string";
      

      我可以看到像 string_concat 这样的函数的使用有限。也许您想处理任意字符串类型或 UTF-8 和 UTF-16 之间的自动转换...

      【讨论】:

        猜你喜欢
        • 2017-08-27
        • 2011-07-12
        • 1970-01-01
        • 2013-07-10
        • 2010-12-16
        • 2018-11-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多