I can't figure out how to get a std::string
reference into an std::unordered_map
using a std::reference_wrapper
. Per the following link I understand I need to overload operator==
.
Why can template instances not be deduced in `std::reference_wrapper`s?
However, I can't figure out how to write operator==
such that it will take a const std::reference_wrapper
. If the wrapper were not const it would not be a problem.
Using a char instead of std::string
works fine (doesn't require overloading operator==
).
Code:
#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
}
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; }
You cannot provide your own overload for operator==
for non-user-defined types. That is, at best, undefined behavior. However, you don't need to do that here. std::unordered_map
has five template parameters:
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;
See the 4th one? That's what you want. You need to provide a function to compare. Luckily, you can use std::hash and std::equal_to like this:
std::unordered_map<
std::reference_wrapper<std::string>,
int,
std::hash<std::string>,
std::equal_to<std::string>
> stringMap;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With