博客 / 詳情

返回

模板的優化

嵌套時(比如printVector<vector<int>>)中的">>"的優化

在使用vector<int>時,本意是向模板中傳入一個vector<int>類型的參數,但是編譯器錯誤的將">>"識別為右移運算符,而不是模板參數表的結束。之前的解決方案是在">>"中間添加空格"> >"。

C++11優化了這一問題,使得不添加空格也可以正確的編譯。

#include <iostream>
#include <vector>
using namespace std;

template<typename T>
class Base {
public:
	void printVector(T& t) {
		auto it = t.begin();
		for (; it != t.end(); it++) {
			cout << *it << " ";
		}
		cout << endl;
	}
};

int main() {
	vector<int> v{ 1,2,3,4,5,6,7,8,9 };
	Base<vector<int>> b;
	b.printVector(v);
    
	system("pause");
	return 0;
}

在c++11之前會報error:

test.cpp:25:20: error: '>>' should be '> >' within a nested template argument list
     Base<vector<int>> b;

根據錯誤提示中描述模板的兩個右尖括之間需要添加空格,這樣寫起來就非常的麻煩。

C++11改進了編譯器的解析規則,儘可能地將多個右尖括號(>)解析成模板參數結束符,方便我們編寫模板相關的代碼。

上面的這段代碼,在支持C++11的編譯器中編譯是沒有任何問題的。

方法的默認模板參數

在c++11之前,類模板可以有默認的模板參數;但是方法模板不支持有默認的模板參數。

在C++11中添加了對函數模板默認參數的支持。

#include <iostream>
#include <typeinfo>

using namespace std;

template<typename T = int, T t = 520>  //c++11之前就 支持  類模板 默認的模板參數,還定義了非類型參數t的默認值為520
class Test {
public:
	void print() {
		cout << "current value:" << t << endl;
	}
};

template<typename T1 = int,typename T2 = int>
void func(T1 val1 = 'a', T2 val2 = 'b') {
	cout << "val1: " << val1 << ",val2: " << val2 << endl;
}



int main() {
	Test<> t;
	t.print();
	Test<int, 1024> t2;
	t2.print();
	cout << endl; 

	//-------------------------------------------------------------
	//自動推導,根據傳遞的實參
	func('a', 'b'); //自動推導為 func<char, char>
	func<int>('a', 'b'); //顯示的填了第一個模板參數,第二個自動推導為char  func<int, char>
	func(1, 2); //推導為 func<int, int> 且默認就是int
	func(1.1, 2.2); //推導為 func<double, double>
	func<char>('a', 'b'); //第一個顯示填了char,第二個自動推導為char func<char, char>
	func<int, char>('a', 'b'); //顯示填了<int, char>   func<int, char>
	func<char, int>('a', 'b'); //顯示填了<char, int>   func<char, int>
	func();  //默認為int    func<int, int>

	system("pause");
	return 0;
}

輸出:

current value:520
current value:1024

val1: a,val2: b
val1: 97,val2: b
val1: 1,val2: 2
val1: 1.1,val2: 2.2
val1: a,val2: b
val1: 97,val2: b
val1: a,val2: 98
val1: 97,val2: 98

如上面代碼,支持函數模板的默認參數,在使用時就可以根據傳遞的實參自動推導類型,寫起來像普通函數一樣;

但是類模板的默認參數,在使用時如不使用默認參數,仍然需要顯示的定義類型。

當默認模板參數和模板參數自動推導同時使用時(優先級從高到低):

  • 如果顯示的填了參數類型,使用顯示的參數類型;
  • 如果可以推導出參數類型則使用推導出的類型
    • 模板參數類型的自動推導是根據模板函數調用時指定的實參進行推斷的,沒有實參則無法推導
    • 模板參數類型的自動推導不會參考函數模板中指定的默認參數。
  • 如果函數模板無法推導出參數類型,那麼編譯器會使用默認模板參數
  • 如果無法推導出模板參數類型並且沒有設置默認模板參數,編譯器就會報錯。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.