gpt4 book ai didi

c++ - 在 C++ 中定义谓词函数的正确方法

转载 作者:IT老高 更新时间:2023-10-28 21:42:03 28 4
gpt4 key购买 nike

我正在尝试编写用于 STL 算法的谓词函数。我看到它们是定义谓词的两种方式:

(1) 使用如下简单函数:

bool isEven(unsigned int i)   
{ return (i%2 == 0); }

std::find_if(itBegin, itEnd, isEven);

(2) 使用operator()函数如下:

class checker {  
public:
bool operator()(unsigned int i)
{ return (i%2 == 0); }
};

std::find_if(itBegin, itEnd, checker);

我对第二种类型有更多用途,因为我通常想创建一个包含一些成员的谓词对象并在算法中使用它们。当我在检查器中添加相同的 isEven 函数并将其用作谓词时,出现错误:
3.给出错误的语法:

class checker { 
public:
bool isEven(unsigned int i)
{ return (i%2 == 0); }
};

checker c;
std::find_if(itBegin, itEnd, c.isEven);

在编译过程中调用 c.isEven 会出错,说明未定义对某些函数的引用。有人可以解释为什么 3. 给出错误吗?另外,如果有任何关于谓词和迭代器基础知识的指南,我将不胜感激。

最佳答案

指向成员函数的指针需要调用实例,而您只将成员函数指针传递给 std::find_if (实际上你的语法不正确,所以它根本不起作用;正确的语法是 std::find_if(itBegin, itEnd, &checker::isEven),由于我给出的原因,它仍然不起作用)。

find_if function 期望能够使用单个参数(要测试的对象)调用函数,但实际上需要两个参数来调用成员函数:实例 this指针和要比较的对象。

重载 operator()允许您同时传递实例和函数对象,因为它们现在是同一个东西。使用成员函数指针,您必须将两条信息传递给只需要一条信息的函数。

有一种方法可以使用 std::bind (需要 <functional> header ):

checker c;
std::find_if(itBegin, itEnd, std::bind(&checker::isEven, &c, std::placeholders::_1));

如果您的编译器不支持 std::bind , 你也可以使用 boost::bind为了这。尽管这样做比重载 operator() 并没有真正的优势。 .


更详细一点,std::find_if期望与签名 bool (*pred)(unsigned int) 匹配的函数指针或以这种方式表现的东西。它实际上不需要是一个函数指针,因为谓词的类型是由模板绑定(bind)的。任何行为类似于 bool (*pred)(unsigned int)是可以接受的,这就是仿函数工作的原因:可以用单个参数调用它们并返回 bool .

正如其他人所指出的,checker::isEven 的类型是 bool (checker::*pred)(unsigned int)它的行为与原始函数指针不同,因为它需要 checker 的实例被召唤。

一个指向成员函数的指针在概念上可以被认为是一个带有附加参数的常规函数​​指针,this指针(例如 bool (*pred)(checker*, unsigned int) )。您实际上可以生成一个可以使用 std::mem_fn(&checker::isEven) 以这种方式调用的包装器。 (也来自 <functional>)。这仍然对你没有帮助,因为现在你有一个函数对象,它必须用两个参数而不是一个参数来调用,std::find_if还是不喜欢。

使用 std::bind将指向成员函数的指针视为采用 this 的函数指针作为它的第一个参数。传递给 std::bind 的参数指定第一个参数应始终为 &c , 第二个参数应该绑定(bind)到新返回的函数对象的第一个参数。这个函数对象是一个可以用一个参数调用的包装器,因此可以与 std::find_if 一起使用。 .

虽然返回类型为std::bind未指定,您可以将其转换为 std::function<bool(unsigned int)> (在这种特殊情况下)如果您需要显式引用绑定(bind)的函数对象,而不是像我在示例中所做的那样直接将其传递给另一个函数。

关于c++ - 在 C++ 中定义谓词函数的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6854039/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com