在类似的问题(例如here)中已指出,您不能将类方法指针作为std::all_of
的谓词。
但是,在C ++ 17中,我们有std::invoke
,它可以使std::all_of
和类似的函数更容易接受成员函数(甚至成员变量)指针。
更具体地说,以下内容无法在GCC 9.2上编译:
#include <algorithm>
#include <vector>
struct S {
bool check() const { return true; }
};
int main() {
std::vector<S> vs;
std::all_of(vs.begin(), vs.end(), &S::check);
}
此Godbolt link包含一些示例代码和使用调用的all_of
的玩具版本。
为什么有此限制?我想念什么吗?我以为std::invoke
标准化后,它也应该应用于适当的STL函数。
答案 0 :(得分:5)
原因1:没有人提出过建议。 P0312R1提议使指针到成员函数的语言可调用,但遭到拒绝(对此达成共识)
原因2:使用lambda(以及之前的std::bind
),动力很小。如果S
是标准定义类型(例如vector
),则基于其他原因,成员到指针选项将是非法的。
std::all_of(vs.begin(), vs.end(), [](auto const& s) {return s.check();});
答案 1 :(得分:4)
下一代算法(std::ranges
名称空间中的那些算法)完全按照您的建议(https://godbolt.org/z/uaPoJf)接受用std::invoke
调用的谓词:
std::ranges::all_of(vs.begin(), vs.end(), &S::check);
或更短(https://godbolt.org/z/_qiO8G):
std::ranges::all_of(vs, &S::check);
此外,它们接受一个称为“投影”的附加参数,该参数是传递给算法的一元转换函数,该算法在对元素进行运算之前已应用于每个元素。例如(https://godbolt.org/z/gWY-OR):
std::ranges::all_of(vs, std::logical_not(), &S::check);
您已经可以将以上所有内容与Casey Carter的cmcstl2或Eric Niebler的range-v3结合使用。