c/c++ 模板函数的重载
程序员文章站
2022-06-14 23:34:21
模板函数的重载 普通函数可以重载,模板函数也可以重载,但规则复杂 有下面2个函数,名字相同,返回值相同就,参数不同,符合重载。 调用1 c++ std::string s("hi"); const std::string sp = &s; std::cout 所以推导出规则2:同样精准的话,更特殊的 ......
模板函数的重载
普通函数可以重载,模板函数也可以重载,但规则复杂
有下面2个函数,名字相同,返回值相同就,参数不同,符合重载。
template<typename t> std::string moban(const t& t){} template<typename t> std::string moban(t* p){}
调用1
std::string s("hi"); std::cout << moban(s) << std::endl;
结果1:调用的是(const t& t),这个可以简单理解,因为参数不是指针类型,所以不适用于(t* p)。
调用2
std::string s("hi"); std::cout << moban(&s) << std::endl;
结果2:调用的是(t* p)。这个就复杂了,因为2个模板都符合,但是调用哪个呢。
- moban(const string*&) t被绑定到string*。
- moban(string*) t被绑定到string。
因为(const t& t)的实例需要进行普通指针到const指针的转换,(t* p)不需要转换,所以是更精准的匹配。
所以推导出规则1:更精准的匹配会被优先采用。
调用3
std::string s("hi"); const std::string* sp = &s; std::cout << moban(sp) << std::endl;
结果3:调用的是(t* p)。这个就更复杂了,因为2个模板都符合,而且都是同样精准的匹配,但是调用哪个呢。
- moban(const string*&) t被绑定到string*。
- moban(string*) t被绑定到const string。
在此情况下,因为是同样精准的匹配,所以无法区分调用哪个。但是根据重载函数模板的特殊规则,调用了(t* p)。
原因是,(const t& t)本质上可以用于任何类型,包括指针类型,比(t* p)更通用,后者只能用于指针类型。
所以推导出规则2:同样精准的话,更特殊的会被优先采用。
如果非模板函数和模板函数同时存在,构成重载,会调用哪个?
有下面3个函数,名字相同,返回值相同就,参数不同,符合重载。
template<typename t> std::string moban(const t& t){} template<typename t> std::string moban(t* p){} std::string moban(const std::string& s){}
调用4
std::string s("hi"); std::cout << moban(s) << std::endl;
结果4:调用的是非模板的函数。
- (const t& t) t被绑定到string,也是可以被调用的。
但是,非模板优先模板。
所以推导出规则3:非模板和模板同时都适用的时候,非模板的会被优先采用。
调用5
std::string s("hi"); std::cout << moban(s) << std::endl;
结果5:调用的是(t* p),而没有调用非模板函数。
所以看出来,规则3有个特例,就是,如果模板的匹配比非模板的匹配更精准的时候,模板会被优先采用。
- moban(const t& t) t被绑定到char[2]。
- moban(t*) t被绑定到const char。
- moban(const std::string& s) 要求从const char*到string的类型转换。
理由:非模板也是可行的,但是需要进行一次用户定义的类型转换,因此她没有模板的匹配更精准。但是2个模板都可以被调用,但是(t*)更特例化,所以最好调用的是(t*)
所以推导出规则4:非模板和模板同时都适用的时候,非模板如果需要一次用户定义的类型转换,而模板不需要的话,模板会被优先采用。
非模板函数和模板函数的声明位置,导致结果的不同。
有下面4个函数,名字相同,返回值相同就,参数不同,符合重载。
template<typename t> std::string moban(const t& t){} template<typename t> std::string moban(t* p){} std::string moban(const char* p){ return debug_rep(std::string(p)); } std::string moban(const std::string& s){}
调用5
std::cout << moban("hello") << std::endl;