括号运算符重载:谓词函数的参数传递机制疑问
为什么std::any_of能自动传递vector元素给函数对象?
你困惑的核心点在于:std::any_of的内部实现会替你完成函数对象的调用动作,把vector元素作为参数传给operator(),不需要你手动写调用代码。
核心逻辑拆解
先看你熟悉的函数对象示例:add42(8)是你手动调用函数对象的operator()并传入参数8。而在std::any_of场景中,这个调用动作是标准库算法帮你做的:
std::any_of会遍历你传入的迭代器范围(v.cbegin()到v.cend())- 对每个迭代器指向的元素,自动把它作为参数,调用你传入的谓词对象(也就是
DivisibleBy(7)这个实例)的operator() - 只要某次调用返回
true,就立刻终止遍历并返回结果
你的DivisibleBy结构体中,bool operator()(int n) const这个重载的作用,就是定义了这个函数对象被调用时的行为——接收一个int类型的参数(正好匹配vector里的元素类型),返回布尔值,完全符合std::any_of对谓词的要求。
和你的lambda版本对比
你写的lambda版本其实多了一层手动包装:
[](int i) { DivisibleBy db7 = DivisibleBy(7); return db7(i); }
这里lambda自己先接收std::any_of传递的元素i,再手动调用db7(i)。而原版的DivisibleBy(7)直接把函数对象传给std::any_of,省去了这层包装——std::any_of会直接调用这个对象的operator(),并把元素传进去,本质和你手动调用db7(i)是一样的。
用简化版实现看清楚本质
如果自己写一个极简版的any_of,就能直观看到参数传递的过程:
template <typename Iterator, typename Predicate> bool my_any_of(Iterator begin, Iterator end, Predicate pred) { for (; begin != end; ++begin) { // 关键:取出当前元素,传给pred的operator() if (pred(*begin)) { return true; } } return false; }
当你调用my_any_of(v.cbegin(), v.cend(), DivisibleBy(7))时,循环里的pred(*begin)等价于DivisibleBy(7).operator()(*begin)——也就是把vector的每个元素作为参数,传给函数对象的operator()。
内容的提问来源于stack exchange,提问作者vtm11
相关产品推荐
相关产品推荐

