How can I create a <string> set that supports C string searching without an intermediary std :: string?

Let's say I have std::set<std::string>

and I want to know if it contains the string "name":

#include <string>
#include <set>
using namespace std;
bool has_name(const set<string> &s) {
    return s.find("name") != s.end();
}

      

The above function constructs and destroys a temporary std :: string with the value "name". This inefficiency seems unnecessary since std :: string has the ability to compare against const char * directly. I would like to remove this temporary.

I tried to use a custom comparator with overloads:

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

      

However, only the variant that accepts std :: string is called; const char * is ignored.

How can I do this constant string comparison directly, instead of creating an intermediate string?

+3


source to share


1 answer


In C ++ 14, use transparent comparators :

std::set<std::string, std::less<>> s;
//                    ^^^^^^^^^^^

s.find("Hello");  // no temporary

      



The transparent comparison predicate std::less<>

is templated operator()

, and the C ++ 14 containers that specialize in transparent predicates expose template overloads find

.

Transparent comparators are strictly selectable so they std::set<std::string>

don't automatically get new overloads.

+6


source







All Articles