c++官方文档-模版函数和重载

#include<stdio.h>
#include<iostream>
#include<queue>
#include<map>
#include<memory.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <climits>
#include <sstream>
#include <cstdlib>
using namespace std;

/**
 * 重载,函数有不同数目的参数或者是不同类型的参数
 */
int operate(int a, int b)
{
	return (a * b);
}
/**
 *注意只有返回类型不同不是重载
 */
double operate(double a, double b)
{
	return (a / b);
}
/**
 * 重载的函数可能会有同样的定义,比如下面这俩个函数
 */

int sum(int a, int b)
{
	return a + b;
}
double sum(double a, double b)
{
	return a + b;
}

/**
 * 泛型
 * template <template-parameters> function-declaration
 * parameter class type or typename type
 *
 */
template<class someType> someType sum(someType a, someType b)
{
	return a + b + 8;
}
/**
 * In all cases, it represents a generic type that will be determined on the moment the template is instantiated.
 * 代表泛型的类型在模版实列化的时候决定
 */
template<typename someType> someType sum2(someType a, someType b)
{
	return a + b + 8;
}
/**
 * Instantiating a template is applying the template to create a function using particular types or values for its template parameters
 *实例模版指应用模版创建一个函数,使用特定的类型或者值转递给模版参数
 *
 *This is done by calling the function template,with the same syntax as calling a regular function,but specifying the template arguments enclosed in angle brackets:
 *由正在被调用的函数模版来完成,就像调用一个普通函数一样,但是需要在尖括号内指定模版参数
 *如下
 *name <template-arguments>(function-arguments)
 *x=sum<int>(10,20)
 *
 *The function sum<int> is just one of the possible instantiations of function template sum. In this case, by using int as template argument in the call, the compiler automatically instantiates a version of sum where each occurrence of SomeType is replaced by int, as if it was defined as:
 *
 *编译器自动生成实例化一个int版本的sum函数,如下
 *
 *int sum (int a, int b)
 *{
 *   return a+b;
 *}
 */
template<typename T, typename R> T fs(T t, R r)
{
	return r + t;
}
template<class T, class U>
bool are_equal(T a, U b)
{
	return (a == b);
}
/**
 *无类型模版参数
 */
template<class T, int N> T fixed_multiply(T val)
{
	return val * N;
}
int main()
{
	int x = 5, y = 2;
	double n = 5.1111, m = 2.0;
	//cout << operate(x, y) << '
';
	//cout << operate(n, m) << '
';
	//模版
	int k = sum<int>(x, y);
	cout << k << endl;
	double dk = sum<double>(n, m);
	cout << dk << endl;
	//注意这个和sum<double>
	dk = sum(n, m);
	//without the type enclosed in angle brackets. Naturally, for that, the type shall be unambiguous. If sum is called with arguments of different types, the compiler may not be able to deduce the type of T automatically.
	//对上面sum的解释,如果尖括号内没有写类型,实际上表示类型任意,如果sum再被调用时参数是不同的类型,编译器可能不能自动推测出T的类型
	cout << dk << endl;
	//把sum函数注释,下面这句话会导致编译不过
	//dk = sum(x,n);
	//注意这俩个
	int kkk = fs<double, int>(n, x);
//	double kkk = fs<double,int>(n,x);
	cout << kkk << endl;

	if(are_equal(10, 10.0))
		cout << "x and y are equal
";
	else
		cout << "x and y are not equal
";
	//are_equal(10,10.0)和are_equal<int,double>(10,10.0)一样
	//没有任意的可能性,因为数字字面量总是会指定类型, integer literals always produce values of type int, and floating-point literals always produce values of type double. Therefore 10 has always type int and 10.0 has always type double.

	//无类型模版参数
	cout<<fixed_multiply<int,2>(10)<<endl;
	cout<<fixed_multiply<int,3>(10)<<endl;
	/**
	 * 上面和template<class int,class int>有个主要的区别
	 *But there exists a major difference: the value of template parameters is determined on compile-time to generate a different instantiation of the function fixed_multiply, and thus the value of that argument is never passed during runtime: The two calls to fixed_multiply in main essentially call two versions of the function: one that always multiplies by two, and one that always multiplies by three. For that same reason, the second template argument needs to be a constant expression (it cannot be passed a variable).
	 *
	 *但是这存在一个主要的区别,模版的参数在编译时被确定用于生成不同fixed_multiply的实例
	 *所以,参数的值永远都不会在运行时传递.在main里面调用的俩个fixed_multiply本质上
	 *调用俩个不同版本的函数,一个总是乘2,一个总是乘3.因此,模版上第二个参数需要是一个常量表达式(它不能传递变量)
	 *
	 *int kkkk = 2 or const int kkkk =2;
	 *cout<<fixed_multiply<int,3>(10)<<endl;
	 */
	//error
//	int kkkk = 4 ;
//	cout<<fixed_multiply<int,kkkk>(10)<<endl;
	//ok
	const int kkkk2 =20;
	cout<<fixed_multiply<int,kkkk2>(10)<<endl;
	return 0;
}