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