class CLASSA { public: int i; CLASSA* copy(){return nullptr;}; }; class CLASSB:public CLASSA { public: int b; }; class HelperMap { public: template<class T1> static void appendMap(map<T1,CLASSA>& m1, const map<T1,CLASSA>& m2) { cout << "template<class T1>" << endl; for (auto it=m2.begin(); it!=m2.end(); it++) { CLASSA* a = dynamic_cast<CLASSA*>(it->second); a->copy(); m1[it->first] = it->second; } }; template<class T1, class T2> static void appendMap(map<T1,T2>& m1, const map<T1,T2>& m2) { cout << "template<class T1, class T2>" << endl; for (auto it=m2.begin(); it!=m2.end(); it++) { m1[it->first] = it->second; } }; }; void append() { map<int,CLASSB*> m1; map<int,CLASSB*> m2; m2[5] = new CLASSB(); HelperMap::appendMap(m1,m2); }
本人想调用appendMap时,当传递的是CLASSA的子类时,就调用到上面那个appendMap函数,当不是CLASSA的子类时才进入下面那个appendMap,要怎么做;
解决方案
30
map<T1, CLASSA*> 和 map<T1, CLASSB*> 是完全不同的类型,没有相互转换的方法,所以通过重载来匹配全部 CLASSA 的子类是不现实的。
通过包含 <type_triats> 头文件可以使用 std::is_base_of ,配合 std::enable_if 可以达到这个效果
通过包含 <type_triats> 头文件可以使用 std::is_base_of ,配合 std::enable_if 可以达到这个效果
template <class T1, class T2> void appendMap(map<T1, T2>& m1, const map<T1, T2>& m2) { cout << "template<class T1, class T2>" << endl; for (auto it = m2.begin(); it != m2.end(); it++) { m1[it->first] = it->second; } } template <class T1, class T2> typename enable_if<is_base_of<CLASSA, T2>::value>::type appendMap(map<T1, T2*>& m1, const map<T1, T2*>& m2) { cout << "template<class T1, class T2 : CLASSA>" << endl; for (auto it = m2.begin(); it != m2.end(); it++) { CLASSA* a = dynamic_cast<CLASSA*>(it->second); a->copy(); m1[it->first] = it->second; } }
这里利用了 T2* 比起 T2 能更精确匹配指针的特性,假如需要匹配 map<T1, CLASSB> 这样的类型,可能需要两个重载都要用 enable_if 处理
10
可写成类,然后对类特化