一、示例代码
C++98中引入了函数模板与类模板,类模板声明中允许默认模板参数,但不支持函数模板默认参数。C++11将这一限制取消。在EditPlusMinGW下,调试如下示例代码:
(本人设置为:^F7用C++11编译,^7用C++98编译)
#include <iostream>
#include <cstdlib>
using namespace std;
template<typename T1, typename T2=int> // C++98和C++11都支持
class Csample
{
public:
Csample(){}
Csample(T1 t1, T2 t2): m_t1(t1), m_t2(t2){}
void Show(void){ cout << m_t1 << '\t' << m_t2 << endl;}
private:
T1 m_t1;
T2 m_t2;
};
template <typename T = int> // C++98不支持,C++11支持
void Show(T t)
{
cout << t << endl;
}
int main()
{
Csample<const char *, int> cs("I am a student! ", 1);
cs.Show();
Show(4);
Show("I am a student!");
return 1;
}
以上代码中的Show(4)将被实例化为Show<const int>(4),Show("I am a student!")将被实例化为Show<const char *>("I am a student!")。在C++98下是无法通过编译的。
二、注意事项
类模板默认参数必须遵守从右到左的规则,而函数模板则不受限制,不知为何这样去设计。这使得C++语法又复杂了。真心希望这些规则能统一。
对模板类:
template<char c='c', typename T2>
class tempA{}
template<typename T1=int, typename T2>
class tempB{}
在C++98和C++11中都不能通过。
而下述代码则可以通过。
对模板函数:
template<char c='c', typename T2>
void Show(T2 t2){ cout << t2 << endl;}
template<typename T1=char, typename T2>
void Show(T1 t1, T2 t2){ cout << t1 << '\t' << t2 << endl;}
均可通过。
三、函数模板参数推导规则:
在此对来自C++11标准草案的示例进行改造。
template<class T, class U=double>
void f(T t=0, U u=0){ cout << t << '\t' << u << endl;}
void g()
{
f(1, 'c');
f(1);
// f(); // 错误,T和U将无法推导
f<int>();
f<int, char>();
}
int main()
{
g();
return 1;
}
运行结果如下:
1 c
1 0
0 0
0
记住:如果能够从函数实参中推导出类型,则默认模板参数类型将被忽略。