我经常要做的事情是在元素集合中找到一个成员,该成员具有给定值的元素。例如给出:
class Person
{
string getName() const {return mName;}
private:
string mName;
};
std::vector<Person> people;
我想找到名字叫"爱丽丝"的人。一种方法是(使用升压范围适配器(:
string toFind = "Alice";
auto iterator = find(people | transformed([](Person const & p){p.getName()}) , toFind );
对于如此简单的操作,这是很多样板。不应该可以做这样的事情吗:
string toFind = "Alice";
auto iterator = find(people | transformed(&Person::getName) , toFind );
(不编译,因为 &Person::getName 不是一元函数(
有没有一种简单的方法可以为成员获取一元函数?
您可以将 std::find_if 函数与适当的 lambda 一起使用,该 lambda 检查getName()
值是否等于字符串tofind
:
std::string tofind = "Alice";
auto it = std::find_if(people.begin(), people.end(), [&tofind](const Person& o) {return o.getName() == tofind; });
if (it != std::end(people)) {
std::cout << "Contains: " << tofind << 'n';
}
else {
std::cout << "Does not contain: " << tofind << 'n';
}
这将要求 getName
函数位于public
类范围内,并且应提供适当的构造函数。完整代码将是:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
class Person {
public:
Person(const std::string& name) : mName{ name } {}
std::string getName() const { return mName; }
private:
std::string mName;
};
int main() {
std::vector<Person> people{ {"John"}, {"Alice"}, {"Jane"} };
std::string tofind = "Alice";
auto it = std::find_if(people.begin(), people.end(), [&tofind](const Person& o) {return o.getName() == tofind; });
if (it != std::end(people)) {
std::cout << "Contains: " << tofind << 'n';
}
else {
std::cout << "Does not contain: " << tofind << 'n';
}
}
您要查找的是std::mem_fn
。它包装了一个指向成员函数的指针,以便可以像自由函数一样调用它,其中调用成员函数的对象作为第一个参数传递。在您的示例中,您可以像这样使用它:
string toFind = "Alice";
auto iterator = find(people | transformed(std::mem_fn(&Person::getName)) , toFind );
// ^^^^^^^^^^^