那些奇奇怪怪的写法

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
发布了83 篇原创文章 · 获赞 3 · 访问量 1235

猜你喜欢

转载自blog.csdn.net/qq_41936794/article/details/105468021