C++ 按对象属性搜索对象向量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15517991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:27:37  来源:igfitidea点击:

Search a vector of objects by object attribute

c++gccstlstd

提问by Christoffer

I'm trying to figure out a nice way to find the index of a certain object in a vector - by comparing a string to a member field in the object.

我试图找出一种很好的方法来查找向量中某个对象的索引 - 通过将字符串与对象中的成员字段进行比较。

Like this:

像这样:

find(vector.begin(), vector.end(), [object where obj.getName() == myString])

I have searched without success - maybe I don't fully understand what to look for.

我搜索没有成功 - 也许我不完全明白要寻找什么。

回答by juanchopanza

You can use std::find_ifwith a suitable functor. In this example, a C++11 lambda is used:

您可以使用std::find_if合适的函子。在此示例中,使用了 C++11 lambda:

std::vector<Type> v = ....;
std::string myString = ....;
auto it = find_if(v.begin(), v.end(), [&myString](const Type& obj) {return obj.getName() == myString;})

if (it != v.end())
{
  // found element. it is an iterator to the first matching element.
  // if you really need the index, you can also get it:
  auto index = std::distance(v.begin(), it);
}

If you have no C++11 lambda support, a functor would work:

如果您没有 C++11 lambda 支持,函子可以工作:

struct MatchString
{
 MatchString(const std::string& s) : s_(s) {}
 bool operator()(const Type& obj) const
 {
   return obj.getName() == s_;
 }
 private:
   const std::string& s_;
};

Here, MatchStringis a type whose instances are callable with a single Typeobject, and return a boolean. For example,

这里,MatchString是一个类型,它的实例可以用单个Type对象调用,并返回一个布尔值。例如,

Type t("Foo"); // assume this means t.getName() is "Foo"
MatchString m("Foo");
bool b = m(t); // b is true

then you can pass an instance to std::find

然后你可以将一个实例传递给 std::find

std::vector<Type>::iterator it = find_if(v.begin(), v.end(), MatchString(myString));

回答by Arne Mertz

In addition to the Lambda and the handwritten functor used by juancho, you have the possibility to use boost::bind(C++03) or std::bind(C++11) and a simple function:

除了 juancho 使用的 Lambda 和手写函子之外,您还可以使用boost::bind(C++03) 或std::bind(C++11) 和一个简单的函数:

bool isNameOfObj(const std::string& s, const Type& obj)
{ return obj.getName() == s; }

//...
std::vector<Type>::iterator it = find_if(v.begin(), v.end(), 
  boost::bind(&isNameOfObj, myString, boost::placeholders::_1));

Or, if Typehas a method isName:

或者,如果Type有一个方法isName

std::vector<Type>::iterator it = find_if(v.begin(), v.end(), 
  boost::bind(&Type::isName, boost::placeholders::_1, myString));

This is just for completeness. In C++11 I'd prefer Lambdas, in C++03 I'd use bind only if the comparison function itself exists already. If not, prefer the functor.

这只是为了完整性。在 C++11 中,我更喜欢 Lambdas,在 C++03 中,我只在比较函数本身已经存在时才使用 bind。如果没有,则更喜欢函子。

PS:Since C++11 has no polymorphic/templated lambdas, bind still has it's place in C++11, e.g. if the parameter types are unknown, hard to spell, or otherwise not easy to deduce.

PS:由于 C++11 没有多态/模板化的 lambdas,bind 在 C++11 中仍然占有一席之地,例如,如果参数类型未知、难以拼写或不容易推断。

回答by uniqrish

A simple iterator may help.

一个简单的迭代器可能会有所帮助。

typedef std::vector<MyDataType> MyDataTypeList;
// MyDataType findIt should have been defined and assigned 
MyDataTypeList m_MyObjects;
//By this time, the push_back() calls should have happened
MyDataTypeList::iterator itr = m_MyObjects.begin();
while (itr != m_MyObjects.end())
{
  if(m_MyObjects[*itr] == findIt) // any other comparator you may want to use
    // do what ever you like
}