可变参数宏,其可变参数没有参数
Variadic macro with no arguments for its variadic parameter
是否合法调用一个可变宏M
没有参数为其可变参数?
相关标准报价为[cpp.replace]/4:
如果宏定义中的标识符列表不以省略号结尾,则调用类函数宏时实参的数量(包括不包含预处理令牌的实参)应等于宏定义中的形参数量。否则,调用中的实参将多于宏定义中的参数(不包括
...
)。必须存在一个终止调用的)
预处理令牌。
对于没有非可变参数的情况,M()
形式的调用应该是合法的,因为调用只有一个参数(不包含预处理令牌)。这样就比非可变形参多了一个实参
对于只有一个非可变参数的情况,是否应该像M(1,)
一样在后面加上,
来为可变参数引入一个不包含预处理令牌的参数?否则,实参的数量将等于非可变形参的数量。例如,
#define variadic(x,...) #__VA_ARGS__
variadic(1,) // 2 arguments: ok
variadic(1) // 1 argument: wrong?
然而,Clang和GCC都接受以下测试用例:#include <iostream>
#define variadic(x,...) #__VA_ARGS__
int main()
{
std::cout << "'" variadic(1) "'" << std::endl;
}
和产生作为输出:
''
这是不标准的行为吗?
否则,调用中的实参将多于宏定义中的形参(不包括…)。
这个从标准中提取的部分表明你的代码不应该是有效的:你有一个参数加上省略号。如果我们遵循上面的标准部分,您应该至少有两个参数。当你写varidadic(1)
时,你只提供一个参数。您的代码无效。
main.cpp:7:32: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu]
std::cout << "'" variadic(1) "'" << std::endl;
和GCC也产生一个警告:
main.cpp:7:32: warning: ISO C99 requires rest arguments to be used [enabled by default]
std::cout << "'" variadic(1) "'" << std::endl;
由于这可能会给程序员带来麻烦,而且程序员的意图很容易猜测,因此他们都认为variadic(1)
等同于variadic(1,)
。
相关文章:
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- 如何使用可变参数模板强制转换每个变体类型
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 调用参数排列不变函数 f(i++, i++)
- 参数归纳与标准::变体
- 模板化回调参数的逆变,如 C# 中的逆变
- 如何在没有参数包的情况下编写变差函数
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 获取模板参数的成员变量值列表
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 如何定义变体<x,y,z>提取模板参数的子类型
- 正确对齐内存模板,参数顺序不变
- 递归中不同参数类型的变元模板函数
- 通过函数指针传递给变差函数的参数会更改其值
- 提升预定义为带有参数的全局 lambda 的变体访问者
- 使用可变参数模板参数提升变体访问者
- boost ::变体 - 为什么模板参数比const字符串参数具有更高的优先级
- 将变参数包中的值加载到临时数组中
- 使用额外参数提升变体访客
- 正在将动态数组元素解析为参数?(变音符)