STL方法调用能否被编译器省略?以std::ranges::count_if场景为例
编译器是否必须执行第二个
std::ranges::count_if调用? 场景代码
#include <algorithm> #include <vector> class T {/*...*/}; bool predicateA(const T& t) {/*...*/} bool predicateB(T& t) {/*...*/} bool evaluate(std::vector<T>& vA, std::vector<T>& vB) { return std::ranges::count_if(vA, predicateA) + std::ranges::count_if(vB, predicateB); }
问题描述
已知如果std::ranges::count_if(vA, predicateA)返回正值,那么无论第二个count_if调用返回什么值,evaluate函数最终都会返回true。请问编译器是否仍必须执行第二个std::ranges::count_if调用?需注意,省略该调用可能改变程序行为,因为predicateB允许存在副作用。
解答
- 编译器必须执行第二个
std::ranges::count_if调用。 - C++标准中仅对特定运算符(比如
&&、||、三元运算符?:)定义了短路求值规则——即当左侧表达式结果已能确定整个表达式结果时,右侧表达式可跳过执行。 - 但这里使用的是
+运算符,标准并未给它赋予短路求值的权限。哪怕第一个count_if的结果已经能让最终返回值确定为true,编译器也不能省略第二个调用。因为predicateB可能带有可见副作用(比如修改外部变量、执行IO操作等),C++要求程序的可见行为必须严格匹配代码的执行逻辑,不能随意跳过会产生副作用的操作。
内容的提问来源于stack exchange,提问作者Dimitrije Kostic
相关产品推荐
相关产品推荐

