类成员用作投影时如何表现得像函数?

问题描述 投票:0回答:1

所以我最近有一个关于使用

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 还是正在进行一些重载选择?

有人能解释一下这个看似神奇的东西是如何工作的吗?

c++ c++20 projection
1个回答
5
投票

&S::a
指向S
类的数据成员
的指针。就像指向成员函数的指针一样,它们都可以通过特定的类对象调用,因此它们是callables。

在c++20中,

ranges
中的约束函数(位于命名空间
<algorithm>
下)和
<ranges>
(或大多数标准库)中的范围适配器通过
std::invoke
统一调用可调用对象。

std::invoke
是用于调用可调用对象的通用接口。除了使用常见形式
f(x)
调用普通函数外,它还可以处理指向数据成员/函数的指针。

让我们回到你的例子。基本上,

ranges::find
通过条件
if (std::invoke(proj, *it) == value)
确定当前元素是否等于该值,其中
proj
&S::a
并且
*it
返回类型为
S
的对象。

因此

std::invoke(&S::a, obj_s)
返回对
a
的成员
obj_s
的引用,这是对
int
的引用。

© www.soinside.com 2019 - 2024. All rights reserved.