如何使用std :: find_if()按成员访问者值进行搜索?

时间:2018-02-07 18:07:53

标签: c++ vector

我正在学习C ++,并且有一个使用对象数据存储数组实现的示例程序。为了使其他操作更容易,我已将商店更改为矢量。通过此更改,我现在不确定搜索商店以根据成员访问者值查找对象的最佳方法。

最初我使用了一个简单的循环:

vector<Composer> composers; // where Composer has a member function get_last_name() that returns a string

Composer& Database::get_composer(string last_name)
{
    for (Composer& c : composers)
        if (c.get_last_name().compare(last_name))
            return c;

    throw std::out_of_range("Composer not found");
}

这当然很好,但是为了实验,我想看看是否还有可以完成工作的矢量特定功能。到目前为止,我已经决定尝试使用find_if()(如果有更好的功能,请建议)。

但是,我不确定使用find_if()的确切方法。基于在线研究中看到的代码,我已将以上内容替换为以下内容:

vector<Composer> composers; // where Composer has a member function get_last_name() that returns a string

Composer& Database::get_composer(string last_name)
{
    auto found = find_if(composers.begin(), composers.end(), 
                [last_name](Composer& c) -> bool {c.get_last_name().compare(last_name);});

    if (found == composers.end())
        throw out_of_range("Composer not found");
    else
        return *found;
}

这不起作用。它确实找到了结果,但它是不正确的。如果一个匹配的参数,比如第三个作曲家的姓氏,该函数总是从向量中返回第一个项(如果我传递的参数不匹配任何该函数正确抛出异常的姓氏)...我做错了什么?

2 个答案:

答案 0 :(得分:2)

你走在正确的轨道上,你的lambda需要返回声明。同样在这种情况下,您不必明确指定它的返回类型,可以推导出它:

find_if(composers.begin(), composers.end(), 
            [last_name](const Composer& c) { return c.get_last_name() == last_name);});

你原始代码不应该编译或至少发出警告,你应该注意它们。

注意:如果您测试它原始代码的工作原理并不清楚,它应该是:

if (c.get_last_name().compare(last_name) == 0 ) 

或简单地说:

if (c.get_last_name() == last_name ) 

因为std::string::compare()返回int -1 0或1,所以您的代码会搜索与变量last_name不匹配的字符串

答案 1 :(得分:0)

使用range-v3,您可以使用投影

auto it = ranges::find(composers, last_name, &composers::get_last_name);