C++ 11 模板函数的默认模板参数

关于默认的函数参数,有一条规则:

void defFunc(int i ,int j = 2,int k = 3) {
}

那就是默认实参必须在形参的右边.

为什么要这么规定? 其实我们调用一下代码就可以发现,必须这样:

defFunc(1); 默认等于 defFunc(1,2,3)
defFunc(1,8); 默认等于 defFunc(1,8,3)

如果不把默认实参放到形参的右边,那么我们的函数很可能就是:

defFunc("默认参数" ,2,3) 

很显然我们就得引入一个标志,告诉编译器这里是一个默认参数.

今天我们要重点讲的是,函数模板和类模板默认模板参数类型的规则:

C++98开始支持引入函数模板和类模板,并且支持类模板的默认类型,但是C++98这个时候还不支持,函数模板默认类型. C++ 11引入了此规则.

template <typename T = int> void defFunc(T a) { //C++ 98不合法,C++ 11合法
}//可以这么写,但是没有什么意义,呵呵!自己想.

类模板默认参数类型和函数默认参数拥有一样的规则:默认实参类型必须在形参的右边.

template<class T, class T1 = int, class T2 = string> class myclass{ //合法

};

以下写法是不合法的.

template<class T = int, class T1 , class T2 = string> class myclass2 { //不合法

};

原因其实和默认函数参数实参类型必须在形参右边是一样的。

类模板本身是一个大家族,模板类是一个具体的大家族中的成员,类似具体下面模板类的写法:

myclass<int ,double ,string> m1; 

只是
myclass<T1,T2,T3>类模板中的一员而已.

和函数同样的理由,如果不这么做,那么我们可以就必须引入一个标志,告诉编译器这是个默认类型,那么就失去默认类型的意义了.

但是再想想,为什么函数参数却不需要遵守这个规则了呢??

肯定是由于某种原因,导致了此规则被破坏.

答案是:函数模板参数类型,编译器支持默认类型的推导。

举个例子:

template<typename T1, typename T2> void func(T1  t1, T2 t2) {
	cout << t1 << endl;
	cout << t2 << endl;
}

在这里插入图片描述

编译器能够根据函数的参数类型自动推导出模板函数,但是模板类就不行,编译器没法自动帮模板类做参数类型的匹配。

下面的模板函数,默认参数类型就是

template<typename T1 = int, typename T2, typename T3> void func2(T2 t2,T3 t3,T1 t1 = 0) {
	cout << t1 << endl;
	cout << t2 << endl;
	cout << t2 << endl;
}

在函数中,可以看到默认的模板类型是不需要遵守必须在右边的规定的.

在这里插入图片描述

因为编译器也能够很轻松的推导出。

猜你喜欢

转载自blog.csdn.net/zhangkai19890929/article/details/83620091