删除宏扩展的尾随逗号
Remove trailing comma of macro expansion
我有一个 'system' 可以使用宏生成 类(不幸的是没有其他方法)。
在某些情况下,例如对于初始化列表,这会导致尾随逗号
我想摆脱:
#define REMOVE_TRAILING_COMMA(...) ?what to put here?
#define FOO a, b, c, d, e, f, g, h,
REMOVE_TRAILING_COMMA(FOO) --> expands to a, b, c, d, e, f, g, h
当然,如果它只是删除最后一个参数也可以。
如果 REMOVE_TRAILING_COMMA(a, b, c)
扩展为 a, b
。
宏总是至少有两个参数,所以最小的情况
将是:REMOVE_TRAILING_COMMA(a,)
--> 扩展为 a
.
这可能吗?我用 Google 搜索了几个小时,但是
什么都没有。
我很乐意使用 #define REMOVE_FIRST(a, ...) __VA_ARGS__
,但这需要颠倒宏参数的顺序。我看不出有什么方法可以做到这一点(除了重载它之外)。因此,根据参数数量重载宏并枚举每个重载以删除尾随参数:
// example macro overoad for up to 9 args
// TODO: write REMOVE_TRAILING_COMMA_{1,2,3,4,5....} for each case
#define REMOVE_TRAILING_COMMA_8(_1,_2,_3,_4,_5,_6,_7,_8) \
_1,_2,_3,_4,_5,_6,_7
#define REMOVE_TRAILING_COMMA_9(_1,_2,_3,_4,_5,_6,_7,_8,_9) \
_1,_2,_3,_4,_5,_6,_7,_8
#define REMOVE_TRAILING_COMMA_N(_1,_2,_3,_4,_5,_6,_7,_8,_9,N,...) \
REMOVE_TRAILING_COMMA_##N
#define REMOVE_TRAILING_COMMA(...) \
REMOVE_TRAILING_COMMA_N(__VA_ARGS__,9,8,7,6,5,4,3,2,1)(__VA_ARGS__)
#define FOO a, b, c, d, e, f, g, h,
REMOVE_TRAILING_COMMA(FOO) --> expands to a, b, c, d, e, f, g, h
Carlo Wood 添加了以下内容:
谢谢!我写了一个小程序来生成上面的内容,所以它是
很容易增加仍然适用的最大参数数量:
#include <string>
#include <iostream>
#include <sstream>
std::string args1_N(int n)
{
std::ostringstream ss;
char const* prefix = "_";
for (int a = 1; a <= n; ++a)
{
ss << prefix << a;
prefix = ",_";
}
return ss.str();
}
int main()
{
int const max_args = 9;
for (int n = 1; n <= max_args + 1; ++n)
std::cout << "#define REMOVE_TRAILING_COMMA_" << n << "(" << args1_N(n) <<
") \\n " << args1_N(n - 1) << std::endl;
std::cout << "#define REMOVE_TRAILING_COMMA_N(" << args1_N(max_args + 1) << ",N,...) \\n" <<
" REMOVE_TRAILING_COMMA_##N\n";
std::cout << "#define REMOVE_TRAILING_COMMA(...) \\n" <<
" REMOVE_TRAILING_COMMA_N(__VA_ARGS__";
for (int a = max_args + 1; a > 0; --a)
std::cout << "," << a;
std::cout << ")(__VA_ARGS__)" << std::endl;
}
我有一个 'system' 可以使用宏生成 类(不幸的是没有其他方法)。
在某些情况下,例如对于初始化列表,这会导致尾随逗号 我想摆脱:
#define REMOVE_TRAILING_COMMA(...) ?what to put here?
#define FOO a, b, c, d, e, f, g, h,
REMOVE_TRAILING_COMMA(FOO) --> expands to a, b, c, d, e, f, g, h
当然,如果它只是删除最后一个参数也可以。
如果 REMOVE_TRAILING_COMMA(a, b, c)
扩展为 a, b
。
宏总是至少有两个参数,所以最小的情况
将是:REMOVE_TRAILING_COMMA(a,)
--> 扩展为 a
.
这可能吗?我用 Google 搜索了几个小时,但是 什么都没有。
我很乐意使用 #define REMOVE_FIRST(a, ...) __VA_ARGS__
,但这需要颠倒宏参数的顺序。我看不出有什么方法可以做到这一点(除了重载它之外)。因此,根据参数数量重载宏并枚举每个重载以删除尾随参数:
// example macro overoad for up to 9 args
// TODO: write REMOVE_TRAILING_COMMA_{1,2,3,4,5....} for each case
#define REMOVE_TRAILING_COMMA_8(_1,_2,_3,_4,_5,_6,_7,_8) \
_1,_2,_3,_4,_5,_6,_7
#define REMOVE_TRAILING_COMMA_9(_1,_2,_3,_4,_5,_6,_7,_8,_9) \
_1,_2,_3,_4,_5,_6,_7,_8
#define REMOVE_TRAILING_COMMA_N(_1,_2,_3,_4,_5,_6,_7,_8,_9,N,...) \
REMOVE_TRAILING_COMMA_##N
#define REMOVE_TRAILING_COMMA(...) \
REMOVE_TRAILING_COMMA_N(__VA_ARGS__,9,8,7,6,5,4,3,2,1)(__VA_ARGS__)
#define FOO a, b, c, d, e, f, g, h,
REMOVE_TRAILING_COMMA(FOO) --> expands to a, b, c, d, e, f, g, h
Carlo Wood 添加了以下内容:
谢谢!我写了一个小程序来生成上面的内容,所以它是 很容易增加仍然适用的最大参数数量:
#include <string>
#include <iostream>
#include <sstream>
std::string args1_N(int n)
{
std::ostringstream ss;
char const* prefix = "_";
for (int a = 1; a <= n; ++a)
{
ss << prefix << a;
prefix = ",_";
}
return ss.str();
}
int main()
{
int const max_args = 9;
for (int n = 1; n <= max_args + 1; ++n)
std::cout << "#define REMOVE_TRAILING_COMMA_" << n << "(" << args1_N(n) <<
") \\n " << args1_N(n - 1) << std::endl;
std::cout << "#define REMOVE_TRAILING_COMMA_N(" << args1_N(max_args + 1) << ",N,...) \\n" <<
" REMOVE_TRAILING_COMMA_##N\n";
std::cout << "#define REMOVE_TRAILING_COMMA(...) \\n" <<
" REMOVE_TRAILING_COMMA_N(__VA_ARGS__";
for (int a = max_args + 1; a > 0; --a)
std::cout << "," << a;
std::cout << ")(__VA_ARGS__)" << std::endl;
}