如何在<string>没有 std::string 中介的情况下制作一个支持通过 C 字符串查找的集合?

How can I make a set<string> that supports lookup via C string, without a std::string intermediary?

本文关键字:string 支持 一个 集合 查找 字符串 情况下 gt 没有 lt std      更新时间:2023-10-16

假设我有一个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();
}

上面的函数构造并销毁一个值为"name"的临时std::字符串。这种低效似乎没有必要,因为std::string具有直接与constchar*进行比较的功能。我想消除这个暂时的。

我尝试使用带有过载的自定义比较器:

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();
}

然而,只调用采用std::string的变量;const char*被忽略。

如何使该集合直接与常量字符串进行比较,而不是构造一个中间字符串?

在C++14中,使用透明比较器:

std::set<std::string, std::less<>> s;
//                    ^^^^^^^^^^^
s.find("Hello");  // no temporary

透明比较谓词std::less<>有一个模板化的operator(),专门用于透明谓词的C++14容器暴露了find的模板重载。

透明比较器是严格选择加入的,因此std::set<std::string>不会自动获得新的过载。