自定义类指针作为无序映射键

时间:2016-05-27 07:05:01

标签: c++ c++11

我正在尝试使用指向自定义类的指针作为键和整数作为值来实现unordered_map。
我认为指针只是一个地址,所以我不必为unordered_map创建比较模板,因为map会在地址之间进行比较。但我得到编译错误。
我的代码如下进行简单测试。任何人都可以帮我解决我做错了什么吗?

#include <cstdlib>
#include <unordered_map>
#include <iostream>

using namespace std;

class MyClass{
    public:
        MyClass(int id){m_id = id;};
        void PrintThis(){cout << " This is test " << endl;};
        int m_id;
};


class Test{
    public:
        unordered_map<MyClass* mc, int test> mapTest;

};

int main(){
    MyClass* mc1 = new MyClass(1);
    MyClass* mc2 = new MyClass(2);

    Test* tt1 = new Test();
    tt1->mapTest.insert(make_pair<MyClass*, int>(mc1, 10));
    tt1->mapTest.insert(make_pair<MyClass*, int>(mc2, 20));

    auto search = tt1->find(mc1);
    if(search != tt1->end()) {
        search->first->PrintThis();
    }else{
        cout << "not Found " << endl;
    }

}

错误信息如下

./main.cpp:17:44: error: wrong number of template arguments (1, should be 5)
         unordered_map<MyClass* mc, int test> mapTest;
                                            ^
In file included from /usr/include/c++/4.8/unordered_map:48:0,
                 from ./main.cpp:2:
/usr/include/c++/4.8/bits/unordered_map.h:97:11: error: provided for 'template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> class std::unordered_map'
     class unordered_map : __check_copy_constructible<_Alloc>
           ^
./main.cpp: In function 'int main()':
./main.cpp:26:18: error: request for member 'insert' in 'tt1->Test::mapTest', which is of non-class type 'int'
     tt1->mapTest.insert(make_pair<MyClass*, int>(mc1, 10));

如果第17行得到修复,我想我可以管理第26行错误......

提前致谢!

2 个答案:

答案 0 :(得分:5)

我尝试了你的代码,发现了3个问题:

  1. 地图声明:应阅读std::unordered_map<MyClass*, int>
  2. 调用未定义的函数(tt1->find / tt1->end,应该阅读tt1->testMap.XXX
  3. 调用make_pair并不需要模板参数。编译器会推断它们。这实际上会导致问题,因为编译器会尝试调用make_pair(MyClass *&&, int &&)。如果我省略模板参数,它可以工作(make_pair(mc1, 10)
  4. 至于第3点:

    make_pair在C ++ 11中声明如下(C ++ 14只添加constexpr(cppreference)

    template< class T1, class T2 >
    std::pair<V1,V2> make_pair( T1&& t, T2&& u );
    

    对于模板参数推导,后续规则适用(参见cppreference

      

    4)如果 P是对cv-nonqualified模板参数的右值引用(所谓的&#34;转发引用&#34;),并且相应的函数调用参数是左值,类型左值引用A 用于代替A进行演绎(注意:这是std :: forward动作的基础)

    (强调我的)

    因此编译器将推断:

    std::make_pair<MyClass *&, int>(MyClass *&, int &&);
    

    其中MyClass *&可以绑定到您的实际参数。

    如果直接指定模板类型,编译器将坚持

    std::make_pair<MyClass *, int>(MyClass *&&, int &&).
    

    由于您的参数是左值,因此无法将其转换为右值引用,并且编译失败

答案 1 :(得分:2)

您对unordered_map<MyClass* mc, int test> mapTest;的声明是无效的语法。它应该是unordered_map<MyClass*, int> mapTest

同时从make_pair来电中删除模板参数,并将tt1->find更改为ttl->mapTest.find(),将ttl->end()更改为ttl->mapTest.end()