【发布时间】:2018-02-04 15:09:42
【问题描述】:
我有以下计算平均值的函数:
template<typename... Ts>
auto mean_of(const Ts... values)
{
return (... + values) / static_cast<double>(sizeof...(Ts));
}
使用 VS 2017 15.6.0 Preview 3 以下代码
std::cout << mean_of(1, 3);
输出2.5。似乎 MSVC 将折叠表达式解释为 1 + 3 / N 而不是 (1 + 3) / N。如果我在折叠表达式周围添加额外的括号,结果是正确的。使用 GCC,不需要额外的括号。
这是 MSVC 中的错误还是我们需要额外的括号?
【问题讨论】:
-
一个相关的困惑:
decltype(x op ...)的行为是什么,带有一个函数参数包的参数? coliru.stacked-crooked.com/a/20448cc227c873fa -
@aschepler 我对这个非常聪明的案例的看法是,由于折叠表达式不是(从语法上讲)一个 id-expression 那么
decltypeshould follow non-entity rules 不管扩张 -
@aschepler a
sizeofvariant 可能展示a [temp.variadic] rule 没有相同的语法陷阱 -
yet another variant,或许在精神上更接近原作
-
@LucDanton 这些都没有让我感到惊讶。之所以会出现差异,只是因为内置的
+将其子表达式强制为纯右值并产生纯右值,但如果扩展中+运算符的数量为零,则不适用。而且我们不能有一个规则,比如“一个参数的一元折叠的类型和值类别就是多个参数的类型”,因为通常每个运算符实例都可能是一个重载的运算符调用,这可能导致任何价值类别和任何可能的类型。
标签: c++ language-lawyer variadic-templates c++17 fold-expression