我正在尝试使用指向自定义类的指针作为键和整数作为值来实现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;
}
}
Run Code Online (Sandbox Code Playgroud)
错误信息如下
./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));
Run Code Online (Sandbox Code Playgroud)
如果第17行得到修复,我想我可以管理第26行错误......
提前致谢!
我尝试了你的代码,发现了3个问题:
std::unordered_map<MyClass*, int>tt1->find/ tt1->end,应该读取tt1->testMap.XXX)make_pair不需要模板参数.编译器会推断它们.这实际上会导致问题,因为编译器试图调用make_pair(MyClass *&&, int &&).如果我省略模板参数,它的工作原理(make_pair(mc1, 10))至于第3点:
make_pair在C++ 11中声明如下(C++ 14刚添加constexpr)(cppreference):
template< class T1, class T2 >
std::pair<V1,V2> make_pair( T1&& t, T2&& u );
Run Code Online (Sandbox Code Playgroud)
对于模板参数推导,适用以下规则(参见cppreference)
4)如果P是对cv非限定模板参数(所谓的"转发引用")的右值引用,并且相应的函数调用参数是左值,则使用对A的类型左值引用代替A进行推导(注意:这是std :: forward动作的基础)
(强调我的)
所以编译器将推断:
std::make_pair<MyClass *&, int>(MyClass *&, int &&);
Run Code Online (Sandbox Code Playgroud)
哪里MyClass *&可以绑定到您的实际参数.
如果直接指定模板类型,编译器将坚持使用
std::make_pair<MyClass *, int>(MyClass *&&, int &&).
Run Code Online (Sandbox Code Playgroud)
由于您的参数是左值,因此无法将其转换为右值引用,并且编译失败