说我有一个std::set<std::string>,我想知道它是否包含字符串"name":
#include <string>
#include <set>
using namespace std;
bool has_name(const set<string> &s) {
return s.find("name") != s.end();
}
Run Code Online (Sandbox Code Playgroud)
上面的函数构造并销毁一个值为"name"的临时std :: string.这种低效率似乎是不必要的,因为std :: string具有直接与const char*进行比较的功能.我想消除这个暂时的.
我尝试使用带有重载的自定义比较器:
struct str_comp_t {
bool operator()(const string &s1, const char *s2) const {
return s1.compare(s2) < 0;
}
bool operator()(const string &s1, const string &s2) const {
return s1.compare(s2) < 0;
}
};
typedef std::set<string, str_comp_t> string_set_t;
bool has_name_2(const string_set_t &s) {
return s.find("name") != s.end();
}
Run Code Online (Sandbox Code Playgroud)
但是只调用带有std :: string的变体; const char*被忽略.
如何使这个集合直接与常量字符串进行比较,而不是构造一个中间字符串?
在C++ 14中,使用透明比较器:
std::set<std::string, std::less<>> s;
// ^^^^^^^^^^^
s.find("Hello"); // no temporary
Run Code Online (Sandbox Code Playgroud)
透明比较谓词std::less<>有一个模板化operator()和C++ 14容器,专门用透明谓词公开模板重载find.
透明比较器严格选择加入,因此std::set<std::string>不会自动获得新的重载.