2013-04-04 143 views
4

我想我可以有一個指針指向一個完全專業的模板功能,但下面的代碼不編譯(MSVC2012)unordered_map構造錯誤(equal_to模板函數)

#include <iostream> 
#include <string> 
#include <unordered_map> 
#include <algorithm> 

using namespace std; 

unsigned long hashing_func(string key) 
{ 
    unsigned long hash = 0; 
    for(int i=0; i<key.size(); i++) 
    { 
     hash += (71*hash + key[i]) % 5; 
    } 
    return hash; 
} 

bool key_equal_fn2(string t1, string t2) 
{ 
    return t1 == t2; 
} 


template<class T> bool key_equal_fn(T t1, T t2) 
{ 
    return t1 == t2; 
} 

template <> bool key_equal_fn<string>(string t1, string t2) 
{ 
    return !(t1.compare(t2)); 
} 

int main() 
{ 
    unordered_map<string, string>::size_type n = 5; 
    unordered_map<string, string> mymap(n, (const std::hash<string> &)hashing_func, (const std::equal_to<string> &)(key_equal_fn<string>)) ; 

    mymap["paul"] = "jenna"; 
    mymap["frank"] = "ashley"; 


    return 0; 
} 

構造線返回以下錯誤:

error C2440: 'type cast' : cannot convert from 'bool (__cdecl *)(T,T)' to 'const std::equal_to<_Ty> &'

+1

跳過類型轉換。 – 2013-04-04 10:54:13

+0

無法將參數3從'bool(__cdecl *)(T,T)'轉換爲'const std :: equal_to <_Ty>&' – Paul 2013-04-04 10:57:19

+1

**絕不**使用C風格轉換。 – 2013-04-04 11:24:07

回答

10

兩個hashing_funckey_equal_fn應函子對象(而不是函數)。此外,它們的類型必須提供給unordered_map模板,也就是說,地圖應該有這樣的類型:

unordered_map<string, string, hashing_func, key_equal_fn> 

其中hashing_funckey_equal_fn是函數子類:

struct hashing_func { 
    unsigned long operator()(const string& key) const { 
     unsigned long hash = 0; 
     for(size_t i=0; i<key.size(); i++) 
      hash += (71*hash + key[i]) % 5; 
     return hash; 
    } 
}; 

struct key_equal_fn { 
    bool operator()(const string& t1, const string& t2) const { 
     return !(t1.compare(t2)); 
    } 
}; 

然後,mymap定義以這種方式:

typedef unordered_map<string, string, hashing_func, key_equal_fn> MapType; 
MapType::size_type n = 5; 
MapType mymap(n, hashing_func(), key_equal_fn()); 

或者,hashing_func和/或key_equal_fn可以是函數,但您必須將它們包裝到std::function對象中。也就是說,

unsigned long hashing_func(const string& key) { 
    unsigned long hash = 0; 
    for(size_t i=0; i<key.size(); i++) 
     hash += (71*hash + key[i]) % 5; 
    return hash; 
} 

bool key_equal_fn(const string& t1, const string& t2){ 
    return !(t1.compare(t2)); 
} 
這樣

typedef unordered_map<string, string, 
    std::function<unsigned long(const string&)>, 
    std::function<bool(const string&, const string&)>> MapType; 

MapType::size_type n = 5; 
MapType mymap(n, hashing_func, key_equal_fn); 

如果你願意,你可以使用lambda表達式和寫作兩個funcions或函數子類避免

並定義mymap

typedef unordered_map<string, string, 
    std::function<unsigned long(const string&)>, 
    std::function<bool(const string&, const string&)>> MapType; 

MapType mymap(n, 
    [](const string& key) -> unsigned long { 
     unsigned long hash = 0; 
     for(size_t i=0; i<key.size(); i++) 
     hash += (71*hash + key[i]) % 5; 
     return hash; 
    }, 
    [](const string& t1, const string& t2) { 
     return !(t1.compare(t2)); 
    }); 

最後,我的最愛是all-lambdas解決方案

auto hashing_func = [](const string& key) -> unsigned long { 
    unsigned long hash = 0; 
    for(size_t i=0; i<key.size(); i++) 
     hash += (71*hash + key[i]) % 5; 
    return hash; 
}; 

auto key_equal_fn = [](const string& t1, const string& t2) { 
    return !(t1.compare(t2)); 
}; 

typedef unordered_map<string, string, 
    decltype(hashing_func), decltype(key_equal_fn)> MapType; 

MapType::size_type n = 5; 
MapType mymap(n, hashing_func, key_equal_fn); 
+0

由於您的代碼片段(std :: function解決了問題),我設法編譯了我的代碼,但現在我遇到了另一個問題,所以我發佈了一個新問題。謝謝! – Paul 2013-04-04 12:02:10