第68課-拾遺:令人迷惑的寫法
阿新 • • 發佈:2018-12-12
第68課 拾遺:令人迷惑的寫法
一、令人迷惑的寫法
template <class T>
class Test{
public:
Test(T t){}
};
template <class T>
void func(T a[], int len){
}
歷史上的原因:
- 早期的C++直接複用class關鍵字來定義模板
- 但是泛型程式設計針對的不只是類型別
- class關鍵字的複用使得程式碼出現二義性
typename
誕生的直接誘因
- 自定義類型別內部的巢狀型別
- 不同類中的同一個識別符號可能導致二義性
- 編譯器無法辨識識別符號究竟是什麼
程式設計實驗:模板中的二義性
#include<iostream>
#include<string>
using namespace std;
template <class T>
class Test{
public:
Test(T t){
cout << "t = " << t << endl;
}
};
template <class T>
void func(T a[],int len){
for(int i = 0;i < len;++i){
cout << a[i] << endl;
}
}
///////////////////////////////////////////////////
int a = 0;
class Test_1{
public:
static const int TS = 1;
};
class Test_2{
public:
struct TS{
int value;
};
};
template <class T>
void test_class(){
typename T::TS* a;
//1. 通過泛指型別T內部的資料型別TS定義指標變數a(推薦的解讀方式)
//2. 使用泛指型別T內部的靜態成員變數TS與全域性變數a進行乘法操作
}
int main(){
//test_class<Test_1>();
test_class<Test_2>();
return 0;
}
typename
的作用:
- 在模板定義中宣告泛指型別
- 明確告訴編譯器其後的識別符號為型別
二、令人迷惑的寫法二
int func(int i) try{
return i;
}
catch(...){
return -1;
}
///////////////////
int func(int i,int j) throw(int){
return i + j;
}
try...catch
用於分隔正常功能程式碼與異常處理程式碼try...catch
可以直接將函式分隔為2部分- 函式宣告和定義時可以直接指定可能丟擲的異常型別
- 異常宣告成為函式的一部分可以提高程式碼可讀性
函式異常宣告的注意事項
- 函式異常宣告是一種與編譯器之間的契約
- 函式宣告異常後就只能丟擲宣告的異常
- 丟擲其它異常將導致程式執行終止
- 可以直接通過異常宣告定義無異常函式
程式設計實驗:新的異常寫法
#include<iostream>
#include<string>
using namespace std;
int func(int i,int j) throw(int , char){
if ( (0 < j) && (j < 10) ){
return (i + j);
}
else{
throw '0';
}
}
void test(int i) try{
cout << "func(i,i) = " << func(i,i) << endl;
}
catch(int){
cout << "Exception:" << i << endl;
}
catch(...){
cout << "Exception:" << endl;
}
int main(int argc,char *argv[]){
test(5);
test(10);
return 0;
}
列印結果:
func(i,i) = 10
Exception:
三、總結
class
可以用來在模板中定義泛指型別(不推薦)typename
是可以消除模板中的二義性try...catch
可以將函式體分為2部分- 異常宣告能夠提供程式的可讀性