C++ 为什么'std::all_'不使用'std::invoke`?

C++ 为什么'std::all_'不使用'std::invoke`?,c++,stl,c++17,C++,Stl,C++17,在类似的问题(例如)中已经注意到,您不能将类方法指针作为谓词传递给std::all_of 然而,在C++17中,我们有了std::invoke,这将使std::all_的和类似的函数很容易接受成员函数(甚至成员变量)指针 更具体地说,以下内容不适用于GCC 9.2: #include包含一些示例代码和使用invoke的all_的玩具版本 为什么会有这样的限制?我错过什么了吗?我想象,当标准化了std::invoke时,它也应该应用于适当的STL函数。原因1:从来没有人提出过它。建议将指向成员函数

在类似的问题(例如)中已经注意到,您不能将类方法指针作为谓词传递给
std::all_of

然而,在C++17中,我们有了
std::invoke
,这将使
std::all_的
和类似的函数很容易接受成员函数(甚至成员变量)指针

更具体地说,以下内容不适用于GCC 9.2:

#include包含一些示例代码和使用invoke的
all_的玩具版本

为什么会有这样的限制?我错过什么了吗?我想象,当标准化了
std::invoke
时,它也应该应用于适当的STL函数。

原因1:从来没有人提出过它。建议将指向成员函数的指针设置为可在该语言中调用,但被拒绝(没有达成一致意见进行此更改)

原因2:使用lambda(以及之前的
std::bind
),动机很小。如果
S
是标准定义的类型(例如
vector
),则由于其他原因,成员到指针选项将是非法的

std::all_of(vs.begin(), vs.end(), [](auto const& s) {return s.check();});

下一代算法(位于
std::ranges
命名空间中的算法)接受使用
std::invoke
调用的谓词,这与您建议的完全一样():

或更短():

此外,它们还接受一个称为“投影”的附加参数,该参数是传递给算法的一元变换函数,在算法对元素进行操作之前应用于每个元素。例如():


您可以将以上所有内容与Casey Carter或Eric Niebler的一起使用。

请参阅Godbolt链接。调用成员函数是
invoke
的目的之一。它是以
*It
作为成员对象调用的,其中
It
所有
实现中的当前迭代器。我现在明白你的观点了。错过了它是一个向量
s
@StoryTeller没问题。仔细看你的问题,我认为你的代码会起作用。可能是实现中的错误?我认为与
bind
相比,
std::mem\u fn
是一个更令人信服的原因(在可读性方面)。我很高兴你提到
mem\u fn
。你是对的,这是令人信服的。出于某种原因,我个人在处理这一系列函数时总是很困难。我发现lambda语法最具可读性。但我坦率地承认,我的偏好是非常主观的。原因3:它不应该使用invoke,我们应该让指向成员的指针可以调用(我觉得有义务在相关的地方发表这一评论)。我感谢你的回答,我知道lambdas。然而,必须编写lambda来表示语言中已经存在的概念(即方法指针),这感觉有点傻。更不用说添加的样板文件以及这正是
std::invoke
的用例。顺便问一下:如果
S
是std定义的类型,那么指向成员的指针为什么是非法的?
std::ranges::all_of(vs.begin(), vs.end(), &S::check);
std::ranges::all_of(vs, &S::check);
std::ranges::all_of(vs, std::logical_not(), &S::check);