有趣的问题。
纠正我的第一个解释,在我看来 g++ 和 clang++ 是正确的,而 MSVC 是错误的。
我想这是因为在 C++17 的 n4659 草案中(抱歉:我无法访问最终版本)我看到了除法运算符涉及“乘法表达式”的表达式规则(A.4)规则如下
乘法表达式/ pm 表达式
“乘法表达式”也可以是“ pm-expression ”,可以是“ cast-expression ”,可以是“ unary-expression ”,可以是“ postfix-expression ”,可以是“ primary-expression ” " 这可以是一个 "折叠表达式"
所以规则可以看成
折叠表达式/ pm 表达式
所以,如果我没记错的话,应该在应用除法之前将“折叠表达式”作为一个整体进行评估。
我的第一个解释(MSVC 正确,g++ 和 clang++ 错误)是基于 17.5.3 的仓促讲座
折叠表达式的实例化产生:
(9.1) ((E1 op E2) op ···) op EN 用于一元左折叠
和 8.1.6
形式为 (... op e) 的表达式,其中op是折叠运算符,称为一元左折叠。
所以我以为
return (... + values) / static_cast<double>(sizeof...(Ts));
应该被实例化
return ((v1 + v2) + ... ) + vn / static_cast<double>(sizeof...(Ts));
无论如何......正确的MSVC......可以肯定......你想要
return (1 + 3) / 2.0;
我建议您添加另外几个括号。