C++重载函数调用疑问:为何传入map迭代器解引用会调用pair参数版本?
为什么调用
AreIdentical时匹配的是std::pair版本而非map::iterator版本? 这事儿其实得从两个核心点来拆解:实参的实际类型,以及C++模板参数推导的规则。
1. 你的实参刚好完美匹配std::pair版本的函数
当你写*orgitem.begin()时,orgitem是std::map<int, std::vector<int>>类型,它的迭代器解引用后得到的是std::pair<const int, std::vector<int>>(map的元素天生是key为const的pair)。
这个类型和你定义的Func1:
template<typename T1, typename T2> bool AreIdentical(const std::pair<T1, T2> &lhs, const std::pair<T1, T2> &rhs)
的参数完全兼容——编译器可以自动推导出T1 = const int,T2 = std::vector<int>,所以Func1是一个合法的候选函数,而且匹配度极高。
2. map::iterator版本的函数因为模板推导失败被排除了
再看你定义的Func2:
template<typename T> bool AreIdentical(typename std::map<int, std::vector<T>>::iterator itOrig, typename std::map<int, std::vector<T>>::iterator itNew)
这里的模板参数T藏在typename std::map<int, std::vector<T>>::iterator这个嵌套类型里面,这属于C++模板中的非推导上下文。
简单来说:编译器没办法从你传入的std::map<int, std::vector<int>>::iterator实参,逆向推导出模板参数T的值。虽然我们肉眼能一眼看出T是int,但C++的模板推导规则不允许编译器做这种“解析嵌套类型别名来反推模板参数”的操作。因为推导失败,Func2根本不会被纳入候选函数列表,自然不会被调用。
如果你想调用Func2怎么办?
你需要显式指定模板参数,同时注意Func2的参数是迭代器(不是解引用后的pair),所以调用方式应该是:
AreIdentical<int>(orgitem.begin(), newitem.begin());
内容的提问来源于stack exchange,提问作者Md. Parwez Akhtar
相关产品推荐
相关产品推荐

