当没有传递参数时,#__VA_ARGS__应该生成什么?
What is #__VA_ARGS__ supposed to generate when there are no arguments passed?
示例代码:
#define FOO(...) You passed: #__VA_ARGS__
FOO(1,2,3)
FOO()
使用Visual c++ (version 14 CTP)进行预处理,得到:
You passed: "1,2,3"
You passed:
在最后一行,#__VA_ARGS__
变成了虚无。我希望它变成"
对于应该发生的事情是否有明确的参考?我用谷歌搜索了很多,但都没有找到。
任何建议的变通方法也很有用。
/ 6.10.3.2 #操作符 (C11):
<语义/h3>
2 -[…]空参数对应的字符串字面值为
""
。[…]
所以我认为MSVC在这里是不正确的。
我将使用字符串字面值连接来解决这个问题:#define FOO(...) You passed: "" #__VA_ARGS__
标准(ISO14882:2011(e))中的段落有点长,但很清楚:
16.3.2 # operator
2一个字符串字面值是一个字符串字面值没有前缀。如果,在替换列表中,参数为立即前面有一个#预处理标记,两个标记都被单个标记取代字符串字面值预处理记号,其中包含的预处理令牌序列的拼写论点。参数之间每次出现空格预处理令牌成为字符中的单个空格字符字符串文字。第一个预处理令牌和之前的空白在删除包含参数的最后一个预处理令牌之后。中的每个预处理标记的原始拼写参数保留在字符串字面值中,除了生成字符串字面值和的拼写的特殊处理字符字面量:在每个"answers"之前插入一个字符字符字面值或字符串字面值(包括分隔"字符")。如果替换的结果不是一个有效的字符串字面量,行为未定义。的与空参数对应的字符串字面值是"。操作符#和##的求值顺序未指定。
由于
16.3.1参数替换
2标识符
__VA_ARGS__
,出现在替换列表中将被视为一个参数,而变量的参数应形成用于替换它的预处理令牌。
相关文章:
- 如何修复带有 clang 的参数'args'缺少默认参数的问题?
- CPPYY/CTYPES 将字符串数组作为 char* args[] 传递
- 如何使模板函数像 R f<void(int)>(args...)
- 怎么可能写 f( *this, std::forward<Args>(args)... ) 而 f 只用 F f 声明;
- 折叠表达式和参数包:static_assert 内 Args&& 和 Args 之间的区别
- 为什么我不能添加 && 到 Ret (Args...) &?
- Ret(&)(Args...)和Ret(Args...)&有什么区别?
- 什么是 'R(*pf)(void*, Args..)',函数指向方法的指针?
- VS2017模板专用化错误无法从'Class *(__cdecl *)(Args...)'转换为'Class *(__cdecl *)(Args...)'
- 在C++中,如何将参数添加到"Args&&... args"参数列表中?
- "auto o = SomeType(args)"而不是"SomeType o(args)
- C Typedef修复模板ARGS
- 作为参数的'char *args[]'和'char **argv'之间的差异
- 我希望通过使用模板元编程从变量ARGS中进行剥离参数
- C++:将 Args && ... _args传递到嵌套列表的正确方法?
- 声明类型包含未展开的参数包'Args'
- 编译时检查大小是否为..(args) 匹配来自 constexpr 函数的结果
- 名称和派生名称类之间的串联(作为模板args)
- boost ::绑定发送变量的回调args到回调函数
- 如何添加一个空格字符来触发 var args c++ execlp()