【问题标题】:Is it possible to concatenate parameters of variadic macro to form a variable name?是否可以连接可变参数宏的参数以形成变量名?
【发布时间】:2021-12-26 07:27:15
【问题描述】:

我正在尝试实现以下目标:

#define def_name(delim, ...) ??? // how will this variadic macro concatenate its parameters to define a new variable?

// Calling `def_name` as follows should define a new variable.

def_name("_", "abc", "def", "ghi");

// The following code should be generated after invoking the above macro.

inline constexpr char const abc_def_ghi_name[]{"abc_def_ghi"};

// Invoking the macro as:

def_name("", "abc", "def", "ghi");

// should produce the following code:

inline constexpr char const abcdefghi_name[]{"abcdefghi"};

def_name 宏应该是什么来支持上述用例?另外,是否可以在编译时使用 C++ 模板/constexpr 实现类似的功能?

【问题讨论】:

  • 搜索 stringify.
  • 你可以改成def_name(_, abc, def, ghi)吗?
  • @NateEldredge 是的,这也没关系。但是如何提供一个空的分隔符呢?
  • 参数的数量真的必须是任意的,还是可以设置一个上限,比如 10 之类的?
  • @NateEldredge 理想情况下,任意数量的参数都很好,但预定的上限也可以。

标签: c++ c++17 string-concatenation variadic-macros


【解决方案1】:

几乎没有语法变化(MACRO 可以字符串化,但不能取消字符串化),您的用法可能是:

def_name(, a, b)
def_name(_, a, b, c)

你可以这样做,但有一些上限:

#define def_name1(sep, p1) \
    inline constexpr char const p1##_name[]{#p1};
#define def_name2(sep, p1, p2) \
    inline constexpr char const p1##sep##p2##_name[]{#p1 #sep #p2};
#define def_name3(sep, p1, p2, p3) \
    inline constexpr char const p1##sep##p2##sep##p3##_name[]{#p1 #sep #p2 #sep #p3};
// ...

为了分派给正确的人,一些实用程序:

#define COUNT_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...)    N
#define COUNT(...)   COUNT_N(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
// Warning: COUNT() return 1 (as COUNT(A)) :-/

#define IDENTITY(N) N
#define APPLY(macro, ...) IDENTITY(macro(__VA_ARGS__))

最后

#define DISPATCH(N) def_name ## N
#define def_name(sep, ...) IDENTITY(APPLY(DISPATCH, COUNT(__VA_ARGS__)))(sep, __VA_ARGS__)

Demo

【讨论】:

  • constexpr 和宏的完美结合 :) 我接受你的回答,但我想我会使用纯 constexpr 解决方案,而不是混合宏和 constexpr。
  • @MeekaaSaangoo:该解决方案中没有“constexpr”(它只是为了尊重您的预期输出而存在)。没有 MACRO 就无法完成字符串化和令牌操作:/(您确实可以将 string/std::array 与 constexpr 连接起来)。
猜你喜欢
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
  • 2014-12-15
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
  • 1970-01-01
相关资源
最近更新 更多