1

我经常要做的事情是在元素集合中找到一个成员,该成员具有给定值的元素。例如给出:

class Person
{
   string getName() const {return mName;}
   private:
   string mName;
};

std::vector<Person> people;

我想找到名为“Alice”的人。一种方法是(使用升压范围适配器):

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 不是一元函数)

有没有一种简单的方法可以为成员获取一元函数?

4

2 回答 2

3

您可以使用带有适当lambda的std::find_if函数来检查值是否等于字符串: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';
    }
}
于 2018-03-09T11:28:07.903 回答
1

您正在寻找的是std::mem_fn. 它包装了一个指向成员函数的指针,以便可以像自由函数一样调用它,其中调用成员函数的对象作为第一个参数传递。在您的示例中,您可以像这样使用它:

string toFind = "Alice";    
auto iterator = find(people | transformed(std::mem_fn(&Person::getName)) , toFind ); 
                                       // ^^^^^^^^^^^
于 2018-03-09T18:53:41.380 回答