1
template <class T>
class Test
{
public:
Test(T t){}
}
template <class T>
void func(T a[],int len)
{}
关键字template意味着我们要定义一个模板,那定义模板肯定要有泛指类型,那么泛指类型在哪里呢,T就是我们要的泛指类型,那为什么T前面是关键字class而不是关键字typename呢?其实这里的T确实是一个泛指类型,这是C++发展的历史原因,早期的C++直接复用class关键字来定义模板,但是泛型编程针对的不只是类类型,所以使用class关键字的使得代码出现二义性,比如以下代码
class Test_1
{
public:
static const int TS = =1;
};
class Test_2
{
public:
struct TS
{
int value;
}
};
template <class T>
void test_class()
{
T::TS * a;//产生歧义
//1.通过泛指类型T内部的数据类型T5定义指针变量a
//2.使用泛指类型T内部的静态成员变量TS与全局变量a进行乘法操作
}
所以后面就出现了typename代替class定义泛指类型的做法**,typename的作用有两个,第一个是定义泛指类型,第二个是明确告诉编译器紧跟其后的标识符是一个类型,所以使用typename定义就不会产生歧义**
2
int func(int i)try
{
return i;
}
catch(...)
{
return -1;
}
这里的try…catch这样写是用于分隔正常功能代码与异常处理代码,可以直接将函数实现分隔为2部分
int func(int i,int j)throw(int)
{
return i+j;
}
函数声明和定义时可以直接指定可能抛出的异常类型,其实这里的throw(int)是就是一个异常声明,说明只能抛出int类型的异常,可以提高代码可读性
例子:
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
char fun(char c)throw(char)
{
if('f'<c&&c<'m')
{
return c+1;
}
else
{
throw '0';//如果throw 0将执行错误,因为异常声明时是抛出字符异常
}
}
void test(char i)try
{
cout<<"fun(char c)"<<fun(i)<<endl;
}
catch(char i)
{
cout << "Exception: " << i << endl;
}
int main(int argc, char *argv[])
{
test('a');
test('k');
return 0;
}
结果:
sice@sice:~$ ./a.out
Exception: 0
fun(char c)l