我正在查看“How to properly use references with variadic templates”,想知道逗号扩展能走多远。
以下是答案的变体:
inline void inc() { }
template<typename T,typename ...Args>
inline void inc(T& t, Args& ...args) { ++t; inc(args...); }
由于可变参数被扩展为一个 * 逗号 * 分隔的元素列表,这些逗号在语义上等同于模板/函数参数分隔符吗?或者它们是在词法上插入的,使它们适合于任何(后预处理器)使用,包括逗号运算符?
这在我的GCC-4.6上工作:
// Use the same zero-argument "inc"
template<typename T,typename ...Args>
inline void inc(T& t, Args& ...args) { ++t, inc(args...); }
但当我试着:
// Use the same zero-argument "inc"
template<typename T,typename ...Args>
inline void inc(T& t, Args& ...args) { ++t, ++args...; }
我不断收到解析错误,期待“;“,并且“args”不会扩展它的包。为什么它不起作用?是因为如果“args”为空,我们会得到一个无效的标点符号块吗?是法律的的,还是我的编译器不够好?
(我试过将“args”放在圆括号中,和/或使用后置增量;两者都不起作用。)
2条答案
按热度按时间zqry0prt1#
只有在特定的上下文中才允许解包,逗号分隔的语句不属于这些上下文。扩展是语义上的,而不是词汇上的。但是,这并不重要,因为还有其他几种方法可以实现它。已经有一些模式/习惯用法可以编写简单的变元函数。实现它的一种方法是:
使用一个helper模板函数,它什么也不做:
将表达式传递给此函数,而不是使用逗号运算符:
如果表达式必须更复杂,你可以在扩展中使用逗号操作符。如果一些
operator++
有返回类型void
,这可能会很有用:eni9jsuy2#
C++17增加了fold expression。