Syn*_*ech 3 c++ stl member find
我在使用STL的时候碰到了一个速度突发,看似正常的情况,在这里简化:
class Person {
string Name;
int Age;
};
vector<Person> people;
AddPeople(people);
string s("Bob");
find(people.begin(), people.end(), s);
Run Code Online (Sandbox Code Playgroud)
find想要比较整个班级.
有一些潜在的解决方法:
find完全放弃(混乱,但可以重构):
bool bBob = false;
for (UINT i = 0; i < people.size(); i++) {
if (people[i].Name == s)
bBob = true;
break;
}
Run Code Online (Sandbox Code Playgroud)提供转换运算符(隐式转换不起作用;显式不能使用find):
class Person {
string Name;
int Age;
operator string() {return Name;}
};
Person b ("Bob", 99);
string s ("Bob");
b == s; //doesn’t work
string(b) == s; //works, but no good for find()
Run Code Online (Sandbox Code Playgroud)定义一个独立的相等运算符(简单,有效,但全局公开):
BOOL operator==(Person l, string r) {
return l.Name == r;
}
Run Code Online (Sandbox Code Playgroud)定义成员相等运算符(使比较顺序依赖;对象必须是第一个):
class Person {
string Name;
int Age;
bool operator==(string s) {return Name == s;}
};
Person b ("Bob", 99);
string s ("Bob");
b==s; //works
s==b; //doesn’t work, but not a problem for find()
Run Code Online (Sandbox Code Playgroud)看起来#4是最好的候选人,但似乎没有理想或感觉"STL",有些人有问题.
是否有更好或更合适的方式来实现"STL方式"?
你可以使用std::find_if(由C++ 11 lambdas驱动):
std::string name = "Bob";
// ...
std::find_if(std::begin(people), std::end(people),
[&] (Person const& p) { return p.Name == name; }
Run Code Online (Sandbox Code Playgroud)
请注意,称其为"STL方式"是不合适的.这是C++标准库,而不是STL("标准模板库").STL是C++标准库的容器和算法库的强大灵感,但两者并不相同.有关详细信息,请参阅StackOverflow上的此问答.
编辑:
由于您使用的是不支持lambda的编译器,因此您可以定义自己的仿函数谓词:
struct person_has_name
{
person_has_name(std::string const& n) : name(n) { }
bool operator () (Person const& p) { return p.Name == name; }
private:
std::string name;
};
Run Code Online (Sandbox Code Playgroud)
并以std::find_if这种方式使用它:
std::string name = "Bob";
// ...
std::find_if(people.begin(), people.end(), person_has_name(name));
Run Code Online (Sandbox Code Playgroud)
有几种方法可以做到这一点,所有方法都涉及某种可调用对象和std::find_if.
第一个是使用新的 C++11 lambda:
std::find_if(people.begin(), people.end(), [](const Person& person)
{ return person.Name == "Bob"; });
Run Code Online (Sandbox Code Playgroud)
如果您有一个不支持 lambda 的旧编译器,您可以使用函子对象:
class FindPersonByName
{
std::string name;
public:
FindPersonByName(const std::string& name) : name(name) {}
bool operator()(const Person& person) const
{ return person.Name == name; }
};
std::find_if(people.begin(), people.end(), FindPersonByName("Bob"));
Run Code Online (Sandbox Code Playgroud)
当然,这两者都要求您的班级拥有Namepublic 成员。但是您可以将其更改为使用公共GetName函数并将其添加到类中。
| 归档时间: |
|
| 查看次数: |
11781 次 |
| 最近记录: |