在类似的问题(例如,此处)中已经指出,您不能将类方法指针作为谓词传递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);
}
Run Code Online (Sandbox Code Playgroud)
该Godbolt链接包含一些示例代码和all_of使用invoke 的玩具版本。
为什么有这个限制?我想念什么吗?我以为当std::invoke标准化时,它也应该应用于适当的STL函数。
原因1: 没有人提出过它。 P0312R1建议使该成员函数的指针可在该语言中调用,但被拒绝(对此更改未达成共识)。
原因2:使用lambda(std::bind在此之前),动力不足。如果S是std定义的类型(例如vector),则出于其他原因,成员到指针选项将是非法的。
std::all_of(vs.begin(), vs.end(), [](auto const& s) {return s.check();});
Run Code Online (Sandbox Code Playgroud)
下一代算法(std::ranges命名空间中的算法)接受用 调用的谓词std::invoke,完全按照您的建议(https://godbolt.org/z/uaPoJf):
std::ranges::all_of(vs.begin(), vs.end(), &S::check);
Run Code Online (Sandbox Code Playgroud)
或更短(https://godbolt.org/z/_qiO8G):
std::ranges::all_of(vs, &S::check);
Run Code Online (Sandbox Code Playgroud)
此外,它们接受一个称为“投影”的附加参数,这是一个传递给算法的一元变换函数,该函数在算法对元素进行操作之前应用于每个元素。例如(https://godbolt.org/z/gWY-OR):
std::ranges::all_of(vs, std::logical_not(), &S::check);
Run Code Online (Sandbox Code Playgroud)
您已经可以将上述所有内容与 Casey Carter 的cmcstl2或 Eric Niebler 的range-v3 一起使用。