Boost unordered_flat_map
é muito bom, é bem mais rápido que std::unordered_map
. Estou tentando usá-lo com tipos de chave heterogêneos:
boost::unordered::unordered_flat_map<std::string, int> my_map;
my_map.emplace(std::string("Hello"), 1);
my_map.find(std::string_view("Hello"));
// no instance of overloaded function matches the argument list
argument types are: (std::string_view)
Agora, como criei um mapa que tem o tipo de chave std::string, há uma função find que aceita um std::string, mas também há uma função find modelo que aceita um K, e normalmente essas coisas devem funcionar desde que o contêiner:
- Sabe como fazer hash do tipo heterogêneo e
- Conhece um operador de igualdade que considera o tipo heterogêneo como o lado direito.
Mesmo que eu faça:
auto equal_to = [](auto& lhs, auto& rhs) { return lhs == rhs; };
E passo essa classe de igualdade para o contêiner, ainda recebo o erro:
boost::unordered::unordered_flat_map<std::string, int, decltype(equal_to)> my_map;
Como faço para fazer isso funcionar?
Do cppreference aprendemos que hash/igualdade transparentes permitem pesquisa de chaves heterogêneas :
Então, você pode fazer isso:
Agora, para o que
equal_to
podemos ser preguiçosos e usarstd::equal_to</*void*/>
o que já é transparente:Ao Vivo Em Coliru
Passando todas as assertivas. No meu código, eu provavelmente não confiaria em
equal_to<void>
para evitar surpresas. Você poderia substituir a "Rosetta Stone" do Boostcore::string_view
¹. Você também poderia tornar o hash ainda mais tolerante (por exemplo, expressando-o em termos de Boost ContainerHash).¹ que é interoperável entre muitos, como boost::beast::string_view e std::string_view e muitos outros. No entanto, ele não suporta char-traits configuráveis.
Mais uma solução alternativa, mas preciso de mais espaço =]
Você pode encapsular a pesquisa em uma função (como):
Como o
std::string
é estático, ele não ficará alocando e desalocando continuamente cada chamada de função.