2017-02-10 53 views
0

一個std ::哈希我有一個類:編譯錯誤定義模板類嵌套類

namespace App 
{ 

template<typename A, typename B> 
class MyClass 
{ 
    //... 
    class NestedClass 
    { 
     //... 
    } 
} 

} //namespace App 

我想定義一個std ::散列NestedClass

//Definition of hash functions 
namespace std 
{ 
    //Definition of a hash to use generic pairs as key 
    template<typename A, typename B> 
    struct hash<App::MyClass<A,B>::NestedClass> 
    { 
    public: 
     size_t operator()(const App::MyClass<A,B>::NestedClass &it) const 
     { 
      return std::hash(it.toInt()); 
     } 
    }; 
} 

我得到錯誤:

source.h:1166: error: type/value mismatch at argument 1 in template parameter list for 'template<class _Tp> struct std::hash' 
    struct hash<App::MyClass<A,B>::const_NestedClass> 
               ^

任何想法?謝謝!

+0

nestedclass是私有的嗎?還有:http://stackoverflow.com/help/mcve – xaxxon

+0

當命名一個由模板類型定義的類型時,必須指定它是一個帶有'typename'的類型。改爲使用'typename App :: MyClass :: NestedClass'。 –

+0

@xaxxon如果你在方括號中寫入MCVE,你會得到:[MCVE] – Jonas

回答

3

您可以通過添加typename在適當情況下,通知該符號下面::編譯器改正錯誤的確是一個類型:

template<typename A, typename B> 
struct hash<typename App::MyClass<A, B>::NestedClass> 
{//   ^^^^^^^^ 
public: 
    size_t operator()(const typename App::MyClass<A,B>::NestedClass &it) const 
//       ^^^^^^^^ 
    { 
     return hash(it.toInt()); 
    } 
}; 

現在你會得到一個新的錯誤:

prog.cc:22:12: error: class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used [-Wunusable-partial-specialization] 
    struct hash<typename App::MyClass<A, B>::NestedClass> 
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
prog.cc:21:23: note: non-deducible template parameter 'A' 
    template<typename A, typename B> 
        ^
prog.cc:21:35: note: non-deducible template parameter 'B' 
    template<typename A, typename B> 

它編譯器不可能在此上下文中推導出AB,因爲不能保證所有MyClass<A, B>實例都存在NestedClass。更多信息:

你可能能夠通過假設NestedClass存在和哈希對MyClass<A, B>而不是解決這個問題。提供一些從MyClass訪問NestedClass的方法,你就可以這樣寫:

template<typename A, typename B> 
struct hash<typename App::MyClass<A, B>> 
{ 
public: 
    size_t operator()(const typename App::MyClass<A,B> &it) const 
    {  
     return hash(it.nested.toInt()); 
    } 
}; 
+0

這不適用,因爲嵌套不是主類的簡單成員。這是一種持久性迭代器,用於在主對象內部導航 – galinette

+0

好吧,這意味着我不能直接使用標準哈希容器的NestedClass,除非我完全專門化主類。 – galinette

+0

@galinette:你可以將'NestedClass'移出它的父類,並通過''模板化它嗎? –