我正在尝试找出一种很好的方法来查找向量中某个对象的索引 - 通过将字符串与对象中的成员字段进行比较。
Like this : find(vector.begin(), vector.end(), [object where obj.getName() == myString])
我搜索没有成功 - 也许我不完全明白要寻找什么。
答案 0 :(得分:51)
您可以将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);
}
如果你没有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_;
};
这里,MatchString
是一种类型,其实例可以使用单个Type
对象调用,并返回一个布尔值。例如,
Type t("Foo"); // assume this means t.getName() is "Foo"
MatchString m("Foo");
bool b = m(t); // b is true
然后您可以将实例传递给std::find
std::vector<Type>::iterator it = find_if(v.begin(), v.end(), MatchString(myString));
答案 1 :(得分:6)
除了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));
或者,如果Type
有方法isName
:
std::vector<Type>::iterator it = find_if(v.begin(), v.end(),
boost::bind(&Type::isName, boost::placeholders::_1, myString));
这只是为了完整性。在C ++ 11中,我更喜欢Lambdas,在C ++ 03中,如果比较函数本身已经存在,我只会使用bind。如果没有,请选择仿函数。
PS:由于C ++ 11没有多态/模板化lambda,因此bind仍然在C ++ 11中占有一席之地,例如如果参数类型未知,难以拼写,或者不易推断。
答案 2 :(得分:3)
一个简单的迭代器可能有所帮助。
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
}