当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - undefined reference to std::hash<string>

问题描述:

I'm trying to write a simple factory function for std::unordered_map. The function takes in an iterable which has a begin and end method and whose value_type is a std::pair. The following is the code that I come up with.

#include <string>

#include <unordered_map>

#include <cassert>

#include <algorithm>

template <class Iterable>

std::unordered_map<typename Iterable::value_type::first_type,

typename Iterable::value_type::second_type>

make_unordered_map(Iterable const &iter)

{

return std::unordered_map<typename Iterable::value_type::first_type,

typename Iterable::value_type::second_type>(

iter.begin(), iter.end());

}

int main()

{

std::unordered_map<std::string, int> map =

{{"a", 0}, {"b", 1}, {"c", 2}};

auto result = make_unordered_map(map);

assert(std::equal(result.begin(), result.end(), map.begin()));

return 0;

}

However, I get a long list of linker error, and it basically asks for the std::hash class specialized for std::string.

undefined reference to `std::hash<std::basic_string<char, std::char_traits<char>,

std::allocator<char> > const>::operator()(std::basic_string<char,

std::char_traits<char>, std::allocator<char> >) const'

I'm using GCC 4.6.1, with the -std=c++0x option. I'm pretty sure std::hash<std::string> is defined in basic_string.h, which is included in <string>.

Any idea how this happens?

网友答案:

You're getting your type deduction mixed up. It's important to remove qualifiers from the deduced types, so declare your template like this:

#include <functional>

template <class Iterable>
std::unordered_map<typename std::decay<typename Iterable::value_type::first_type>::type,
                   typename Iterable::value_type::second_type>
make_unordered_map(Iterable const &iter)
{
  return std::unordered_map<
    typename std::decay<typename Iterable::value_type::first_type>::type,
    typename Iterable::value_type::second_type>(iter.begin(), iter.end());
}

Without this, you end up with const std::string as the key type, for which there is no specialization of std::hash.

Check out how real-world library code is written (e.g. the GCC standard library implementation) to see how to handle template types judiciously.

(By the way, std::equal is probably not the best tool for unordered maps.)

分享给朋友:
您可能感兴趣的文章:
随机阅读: