所以我最近有一个关于使用
std::ranges::find
算法的范围变体的问题,答案使用了投影:
if (auto const it{std::ranges::find(iv, 1, &S::a)}; it != iv.end()) {
std::cout << "Found!\n" << "\n";
}
特别是
&S::a
部分。
通常我见过在这个地方使用 lambda,但这里我们使用指向类成员的指针。这是转换为 lambda 还是正在进行一些重载选择?
有人能解释一下这个看似神奇的东西是如何工作的吗?
附注 如果有人有更好的标题建议,请告诉我。
&S::a
是指向类S
的数据成员的指针。就像指向成员函数的指针一样,它们都可以通过特定的类对象调用,因此它们是callables。
在c++20中,
<algorithm>
中的约束函数和<ranges>
中的范围适配器都通过std::invoke
调用可调用对象,这是调用可调用对象的统一通用接口。
让我们回到你的例子。基本上,
ranges::find
通过if (std::invoke(proj, *it) == value)
确定当前元素是否等于value,其中proj
是&S::a
,*it
返回类型为S的对象,因此std::invoke(&S::a, s_obj)
返回对成员的引用
a
的 s_obj
,这是对 int
的引用。