写一个代码,两个数相加,要求在任何形式下都能通用
在预编译阶段处理,相当于文本替换 但是它没有类型检查和安全检查。
void*是半开半闭的区间,非常容易越界
我们考虑到可以用以下形式,可以将类型进行列举,但是类型分为内置类型(int、double等等)和自定义类型(struct结构体、class类类型),函数重载无法对所有自定义类型进行处理
int Sum(int ,int ); double Sum(double ,double );函数模板可以解决以上问题 1、模板就相当于C++中的泛型 2、整个模板的处理是在编译阶段处理的,模板体不编译。 函数模板的编译过程: (1)定义点 只编译模板有头部 (2)调用点 编译模板函数 3、在调用点,将具体的类型传递给<>中的模板类型,进行参数的传递/替换。 但是类型参数化的过程并不是文本替换,而是像类型重定义。
template<typename T> T Sum(T a, T b) { return a + b; } int main() { Sum<int>(10, 20); return 0; }1、如果在调用点直接调用的是函数模板,并且在函数调用点没有给出类型,那么就可以使用模板的实参推演。 例如:在main函数中直接调用Sum(10,20);,它可以调用成功,因为编译器会进行模板的实参推演,进行模板的实例化。 2、注意事项: (1)不能让推演产生二义性 即不能在调用点出现Sum(10,20.1);类型不匹配的情况,编译器不知道该用哪种类型进行推演。 (2)必须要有实参 例如: 在调用点getVal();是错误的,没有实参,应该改为getVal< int >();
template<typename T> T getVal() { static T tmp = 10; return tmp; } int main() { getVal(); return 0; }1、函数模板的特例化实际上是根据类型来进行特殊处理。 2、例如: 这个代码无法将char*类型的"hello", "world"进行比较,如果只是简单的用return a > b;进行比较是错误的,因为字符串的比较时要用到strcmp。
template<typename T> bool Compare(T a, T b) { std::cout << "Compare(T,T)"<< std::endl ; return a > b; } int main() { Compare<int>(10, 20); Compare<double>(10.1, 20.1); Compare<char*>("hello", "world"); return 0; }针对char*类型进行特殊的处理,加上一个模板函数,就是模板特例化的版本。
template<> bool Compare(char* a, char* b) { std::cout << "Compare (char*, char*)" << std::endl; return strcmp(a, b) > 0; }3、注意事项 模板特例化版本应该满足和模板版本相同的逻辑。 例如以上代码要是在模板特例化版本的参数列表中加入const,bool Compare(const T a, const T b),此时const修饰的是a,b。如果给模板版本的参数列表也加const,就必须修饰的也是a,b。