with C++14 we are allowed to compare elements of some associative containers (like std::set) with other types than the ones stored in a container. It's supposed to work when comparator has is_transparent
denoted as a type (see e.g. std::set::find).
Suppose I have a string wrapper which performs some checks on a string (if it's format is valid format and so on - not really important, but constructing it is heavy enough that I'd like to avoid it + it can throw exceptions) and it's stored in std::set to have a container of unique values. How should I write a comparator for it? Should it look like like the one below? Can I overload and use my sw::operator<()
to achieve the same?
class sw
{
public:
explicit sw(const std::string& s) : s_(s) { /* dragons be here */ }
const std::string& getString() const { return s_; }
bool operator<(const sw& other) const { return s_ < other.s_; }
private:
std::string s_;
};
struct Comparator
{
using is_transparent = std::true_type;
bool operator()(const sw& lhs, const std::string& rhs) const { return lhs.getString() < rhs; }
bool operator()(const std::string& lhs, const sw& rhs) const { return lhs < rhs.getString(); }
bool operator()(const sw& lhs, const sw& rhs) const { return lhs < rhs; }
};
int main()
{
std::set<sw, Comparator> swSet{ sw{"A"}, sw{"B"}, sw{"C"} };
std::cout << std::boolalpha << (swSet.find(std::string("A")) != swSet.end()) << std::endl;
}
I believe that above code should work as expected, but when I tested it with g++4.9 and clang++3.6, both yielded errors about missing conversion from string
to key_type
as if string overloads of Comparator::operator()
were never taken into account. Am I missing something?