如何将std::find/std::find_if用于自定义类对象的向量
How to use std::find/std::find_if with a vector of custom class objects?
我有一个类表示一个名为Nick
的用户,我想在它上面使用std::find_if
,在那里我想找到用户列表向量是否包含与我传递的相同用户名的对象。我做了一些尝试,试图为用户名创建一个新的Nick
对象,我想测试和重载== operator
,然后尝试使用find/find_if
对象:
std::vector<Nick> userlist;
std::string username = "Nicholas";
if (std::find(userlist.begin(), userlist.end(), new Nick(username, false)) != userlist.end())) {
std::cout << "found";
}
我已经重载了== operator
,所以比较Nick == Nick2应该工作,但函数返回error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Nick' (or there is no acceptable conversion)
。
这是我的Nick类供参考:
class Nick {
private:
Nick() {
username = interest = email = "";
is_op = false;
};
public:
std::string username;
std::string interest;
std::string email;
bool is_op;
Nick(std::string d_username, std::string d_interest, std::string d_email, bool d_is_op) {
Nick();
username = d_username;
interest = d_interest;
email = d_email;
is_op = d_is_op;
};
Nick(std::string d_username, bool d_is_op) {
Nick();
username = d_username;
is_op = d_is_op;
};
friend bool operator== (Nick &n1, Nick &n2) {
return (n1.username == n2.username);
};
friend bool operator!= (Nick &n1, Nick &n2) {
return !(n1 == n2);
};
};
如果你正在使用c++ 0X,你可以使用一个简单的lambda表达式
std::string username = "Nicholas";
std::find_if(userlist.begin(), userlist.end(), [username](Nick const& n){
return n.username == username;
})
必须在类之外用两个object定义operator==,作为工具函数,而不是成员。
要使它成为友元,只需将函数的声明放在类中。
试试这样:
class Nick {
public:
friend bool operator== ( const Nick &n1, const Nick &n2);
};
bool operator== ( const Nick &n1, const Nick &n2)
{
return n1.username == n2.username;
}
你的find也应该像这样:
std::find(userlist.begin(), userlist.end(), Nick(username, false) );
不需要new
我知道您想重载==
操作符,但是同样的事情可以很容易地用谓词完成:
struct UsernameIs {
UsernameIs( string s ) : toFind(s) { }
bool operator() (const Nick &n)
{ return n.username == toFind; }
string toFind;
};
int main()
{
vector<Nick> vn(10);
string nameToFind = "something";
find_if(vn.begin(), vn.end(), UsernameIs(nameToFind));
}
请注意,在c++ 0x中,您可以更简洁地使用lambda表达式执行相同的操作。
您正在传递一个指向find函数的指针。删除新的:
std::find(userlist.begin(), userlist.end(), Nick(username, false))
同时,你的操作符应该通过const引用接受它们的实参,而不是修改它们。
bool operator== (const Nick &n1, const Nick &n2)
我注意到您正试图以这种方式从一个构造函数调用另一个构造函数:
Nick(std::string d_username, bool d_is_op) {
Nick();
...
嗯,对不起,但这不起作用。Nick()
行只是创建了一个临时变量,并不影响this
。构造函数转发仅在c++ 0x(即将发布的标准)中可行
至于你的问题-这个问题问了几天前关于binary_search涵盖相同的理由。上面的答案太棒了。
std::binary_search的神秘限制
HTH .
注:理想情况下,这应该是一个注释,但它太啰嗦了
可以使用boost::bind
std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::isFound,
_1 ) );
只是实现bool Nick::isFound()
您也可以通过
标准std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::compare,
_1,
nick ) );
实施bool Nick::compare( const Nick & nick )
{
return this->username == nick.username;
}
这个适合我:
Nick.h
#include <string>
class Nick {
private:
Nick() {
username = interest = email = "";
is_op = false;
};
public:
std::string username;
std::string interest;
std::string email;
bool is_op;
Nick(std::string d_username, std::string d_interest, std::string d_email, bool d_is_op) {
Nick();
username = d_username;
interest = d_interest;
email = d_email;
is_op = d_is_op;
};
Nick(std::string d_username, bool d_is_op) {
Nick();
username = d_username;
is_op = d_is_op;
};
bool operator==(const Nick& refNick) const
{
if (username != refNick.username)
return false;
if (interest != refNick.interest)
return false;
if (email != refNick.email)
return false;
if (is_op != refNick.is_op)
return false;
return true;
}
bool operator!=(const Nick& refNick) const
{
if (username == refNick.username)
return true;
if (interest == refNick.interest)
return true;
if (email == refNick.email)
return true;
if (is_op == refNick.is_op)
return true;
return false;
}
};
main.cpp
#include <iostream>
#include <string>
#include <vector>
#include "Nick.h"
int main()
{
std::vector<Nick> userlist;
std::string username = "Nicholas";
Nick Nicholas(username, false);
Nick John("John", true);
userlist.push_back(Nicholas);
std::vector<Nick>::iterator it;
it = std::find(userlist.begin(), userlist.end(), Nick("Nicholas", false));
if(it != userlist.end())
std::cout << "n" << Nicholas.username << " was found.";
else
std::cout << "n" << Nicholas.username << " was not found.";
it = std::find(userlist.begin(), userlist.end(), John);
if (it != userlist.end())
std::cout << "n" << John.username << " was found.";
else
std::cout << "n" << John.username << " was not found.";
}
结果Nicholas was found.
John was not found.
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 在 QVector<std::unique_ptr 上使用 std::find<Type>>
- std::find,返回所有找到的值的替代方法,而不仅仅是存在重复的向量的第一个值
- 为什么在向量上使用 std::find() 时会出现错误?
- 使用 std::find 时没有匹配的函数调用错误
- std::set<Key,Compare,Allocator>::find() 函数使用"<"运算符而不是"=="运算符背后的直觉是什么?
- STL std::find() C++
- 如何将 std::find() 与 2d std: 数组一起使用?
- 为什么 std::find( s.begin(), s.end(), val ) 比集合 s 的 s.find(val) 慢 1000 倍<int>?
- 如果迭代器没有因插入而无效,则使用std::find和C::insert()是线程安全的
- 未按值排序的std::find和std::any_of
- 为什么std::map有find成员函数
- 在libc++和libstdc++之间的std::map上使用std::find时的实现差异
- 有没有办法在Cython中导入std::find find_if等?
- std::map::find 的效率是否与值的数据大小有关?
- std::string::find 为取消引用的迭代器和等效字符串文本返回不同的值
- 使用 find() 通过 std::set 的迭代器将不起作用。出了什么问题?
- Android-NDK 的 GGC/C++ 对于 std::string::find/std::getline(...) 来说似乎不稳定
- MinGW g++ cannot find std::stof
- 如何将std::find/std::find_if用于自定义类对象的向量