我知道we can't use variadic expansions as if it is a chain of comma operators。在那个问题中,样本是这样的:
template<typename... Args>
inline void increment_all(Args&... args)
{
++args...;
}
首先增加或扩大可能是不明确的,因此括号不会受到伤害:
template<typename... Args>
inline void increment_all(Args&... args)
{
(++args)...;
}
或类似的东西:
template<typename... Args>
void cout_all(Args&&... args)
{
(std::cout << std::forward<Args>(args))...;
}
我知道我们可以使用一些递归技巧来获得我们想要的东西,like this。我不知道为什么标准没有描述这种行为?我的意思是,背后的原因是什么?
答案 0 :(得分:5)
允许包扩展的其他上下文是逗号是列表元素之间的分隔符的列表,而不是运算符。
例如,f(args...)
扩展为函数参数列表,tuple<Args...>
扩展为模板参数列表。
在您的示例中,包扩展形成一个语句,语句的子表达式之间的逗号是逗号运算符,可能会重载,导致任意复杂的代码,与内置逗号运算符不同,不< / em>强制从左到右评估。如果您的(std::cout << std::forward<Args>(args))...;
示例以未指定的顺序写出了args,您会感到惊讶,因为参数包中的某个类型会重载operator<<
和operator,
并破坏评估顺序。
这样做不会是对当前规则的简单扩展,它将是一个完全不同的背景,具有非常不同的效果。
不,它不会含糊不清。使用首先增加或扩大可能是不明确的,因此括号不会受到伤害:
f(++args...)
可以,而且清晰明确。您的建议的难点不在于如何解析++args...
在将其扩展为包含逗号运算符的语句后会发生什么。