在std :: unordered_map中重载operator == for const std :: reference_wrapper

时间:2015-09-19 16:50:15

标签: c++ c++11 stl operator-overloading reference-wrapper

我无法弄清楚如何使用std::stringstd::unordered_map引用加入std::reference_wrapper。根据以下链接,我了解到我需要重载operator==

Why can template instances not be deduced in `std::reference_wrapper`s?

但是,我无法弄清楚如何编写operator==,以便 const std::reference_wrapper。如果包装器不是 const ,则不会有问题。

使用char代替std::string可以正常工作(不需要重载operator==)。

代码:

#include <iostream>
#include <unordered_map>
#include <functional>

bool operator==(const std::reference_wrapper<std::string> lhs,
                const std::reference_wrapper<std::string> rhs)
{
    return std::equal_to<std::string>()(lhs.get(), rhs.get());
}

int main(){
    char        chr('a');
    std::string str("b");
    int         num(1);

    // this works (char)
    std::unordered_map<std::reference_wrapper<char>, int, std::hash<char>> charMap;
    std::pair<std::reference_wrapper<char>, int> charPair(chr , num);
    charMap.insert(charPair);
    std::cout << "charMap works.  Output: " << charMap[chr] << std::endl;

    // does not work (std::string)
    std::unordered_map<std::reference_wrapper<std::string>, int, std::hash<std::string>> stringMap;
    std::pair<std::reference_wrapper<std::string>, int> stringPair(str , num);
    stringMap.insert(stringPair);  // compile error
}

编译错误:

error: no match for ‘operator==’ (operand types are ‘const std::reference_wrapper<std::__cxx11::basic_string<char> >’ and ‘const std::reference_wrapper<std::__cxx11::basic_string<char> >’)
       { return __x == __y; }

1 个答案:

答案 0 :(得分:8)

对于非用户定义类型,您无法为operator==提供自己的重载。也就是说,充其量是未定义的行为。但是,你不需要在这里做到这一点。 std::unordered_map五个模板参数:

template<
    class Key,
    class T,
    class Hash = std::hash<Key>,
    class KeyEqual = std::equal_to<Key>,
    class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;

见第4个?这就是你想要的。您需要提供一个比较功能。幸运的是,您可以像这样使用std :: hash和std :: equal_to:

std::unordered_map<
    std::reference_wrapper<std::string>,
    int,
    std::hash<std::string>,
    std::equal_to<std::string>
> stringMap;