如何将非静态成员函数作为remove_if的谓词使用?
remove_if谓词的报错问题 首先咱们得先理清报错的根源:remove_if需要接收一个可调用对象(比如函数指针、lambda、重载了operator()的类实例),但你现在的写法s.operator()(s)是直接执行了这个成员函数,返回的是一个bool值,而非把这个函数作为谓词传递给remove_if。另外非静态成员函数必须绑定到具体的类实例上,才能被当作可调用对象使用。
下面给你几个实用的解决办法,按推荐程度排序:
1. 直接传递类实例(最简单的方案)
因为你的Song类已经重载了operator(),这个类的实例本身就是一个函数对象。你只需要把实例s直接传给remove_if,它会自动调用实例的operator()方法:
Song s = Song(title, artist); songs_.remove_if(s);
这是最贴合函数对象设计意图的写法,简洁又直观。
2. 使用std::bind绑定成员函数与实例
如果你一定要显式处理成员函数指针,可以用std::bind把成员函数和你的实例绑定在一起,记得要包含<functional>头文件:
#include <functional> // ... Song s = Song(title, artist); songs_.remove_if(std::bind(&Song::operator(), &s, std::placeholders::_1));
这里std::bind把Song::operator()成员函数和实例s的地址绑定,std::placeholders::_1代表remove_if遍历容器时会传入的那个Song参数。
3. 用Lambda表达式包裹(灵活度最高)
C++11及以上支持lambda表达式,这种写法可读性更强,也不需要额外的头文件依赖:
Song s = Song(title, artist); songs_.remove_if([&s](const Song& song) { return s(song); // 直接调用实例s的operator()方法 });
Lambda可以方便地捕获外部变量,这里用引用捕获s,然后在lambda内部调用它的operator()。
额外提醒:你的operator()代码有个小问题
你写的string thisArtist = Song::artist_;是错误的,如果artist_是Song的非静态成员变量,不能用类名::成员名的方式访问,应该直接用artist_或者this->artist_(在const成员函数里this是const指针,完全没问题)。修改后这部分代码应该是:
bool Song::operator()(const Song& s) const { SongCallback(); string thisArtist = artist_; // 直接访问成员变量 string thisTitle = title_; // ... 后续逻辑不变 }
内容的提问来源于stack exchange,提问作者Potion

