为 std::unordered_map 中的 const std::reference_wrapper 重载运算符==
Overloading operator== for const std::reference_wrapper in std::unordered_map
我不知道如何使用 std::reference_wrapper
将 std::string
引用引用到 std::unordered_map
中。根据以下 link 我明白我需要超载 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; }
您不能为非用户定义类型的 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;
看到第四个了吗?那就是你想要的。你需要提供一个函数来比较。幸运的是,您可以像这样使用 std::hash 和 std::equal_to:
std::unordered_map<
std::reference_wrapper<std::string>,
int,
std::hash<std::string>,
std::equal_to<std::string>
> stringMap;
我不知道如何使用 std::reference_wrapper
将 std::string
引用引用到 std::unordered_map
中。根据以下 link 我明白我需要超载 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; }
您不能为非用户定义类型的 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;
看到第四个了吗?那就是你想要的。你需要提供一个函数来比较。幸运的是,您可以像这样使用 std::hash 和 std::equal_to:
std::unordered_map<
std::reference_wrapper<std::string>,
int,
std::hash<std::string>,
std::equal_to<std::string>
> stringMap;