MSVC中Fold表达式运算优先级问题咨询:是否需额外括号?
这其实是旧版MSVC的编译器Bug,不过严格来说,从C++标准的角度,你确实应该给折叠表达式加上括号——这不仅能解决当前问题,还能保证代码的标准符合性和跨编译器可移植性。
给你理清楚来龙去脉:
- 根据C++17及后续标准,折叠表达式必须用括号包裹。比如
(args + ...)才是符合标准的一元右折叠写法,不带括号的args + ...属于编译器扩展(GCC、Clang和新版MSVC都支持,但并非标准强制要求的语法)。 - 你使用的VS 2017 15.6.0 Preview 3是比较早期的预览版本,它在处理这种非标准的不带括号折叠时,出现了运算符优先级解析错误:把
args + ... / N错误解析成了第一个参数 + (剩余参数的折叠结果 / N),也就是你看到的1 + 3/N。 - 而GCC对这种扩展写法的解析更符合直觉,它会把
args + ...当成一个完整的折叠表达式,再整体除以N,也就是(1+3)/N。
解决建议
最稳妥、最符合标准的方案是给折叠表达式加上括号,示例代码如下:
template<typename... Args> auto calculate_average(Args... args) { const auto count = static_cast<double>(sizeof...(args)); return (args + ...) / count; // 带括号的折叠表达式,所有编译器均可正确解析 }
这样写不管是旧版MSVC(只要支持C++17折叠特性)、新版MSVC还是GCC/Clang,都会输出正确的平均值。
另外,如果你坚持想用不带括号的扩展写法,升级到较新的MSVC版本即可解决这个Bug——微软在后续的更新中修复了该解析问题,新版MSVC对不带括号的折叠表达式的处理逻辑已经和GCC保持一致。
内容的提问来源于stack exchange,提问作者Evg
相关产品推荐
相关产品推荐

