编译定义模板类嵌套类的std :: hash的错误

时间:2017-02-10 11:19:28

标签: c++ templates hash nested

我有一个班级:

namespace App
{

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

} //namespace App  

我想为NestedClass定义一个std :: hash

//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>
                                                  ^

有什么想法吗?谢谢!

1 个答案:

答案 0 :(得分: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,因为不能保证所有NestedClass实例都存在MyClass<A, B>。更多信息:

您可能会假设NestedClass存在并在MyClass<A, B>上进行哈希处理,从而解决此问题。提供一些从NestedClass访问MyClass的方法,您就可以写出这样的内容:

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());
    }
};