前言
前一節分析了關於template
的使用注意, 本節分析關於template
非類型參數的使用, 非類型參數可能在有些人認爲並沒有太大作用, 但是既然C++規定有能這樣使用就肯定有其意義, 這裏就做一個淺析.
非類型模板參數
非類型參數, 可用在模板中自定義爲整型類型, 指針或引用, 不能定義爲浮點數等其他類型.
非類型模板參數在編譯期間就已經實例化, 所以其模板實參必須是常量表達式.
template<int N>; // N是編譯時就確定的常量表達式
template<size_t N, size_t M>; // N,M是編譯時就確定的常量表達式
可能就是會覺得沒有用, 畢竟使用模板就是要用他的模板參數類型啊, 沒有這個那還怎麼用. 這裏就來先看一個例子.
要求: 實現一個函數返回一個數組的真實大小, 如 : int a[100]; ArrSize(a);返回100
嗯? 講道理傳入函數中a就轉換爲指針了, 怎麼用指針能獲取其表示範圍? 這裏就要用到template
的非類型參數.
template<class T, std::size_t N> // 這裏的N是編譯時期就知道了, 所以可以加上constexpr關鍵字
constexpr std::size_t ArrSize(T (&a)[N]) noexcept
{
return N;
}
int a[100]; ArrSize(a);
實現了這個功能後我們就來分析一下.
函數模板通過傳入a後會自動推導出 T 的類型爲 int, N 的大小爲 100, 函數通過引用, 所以傳入的是一個a而不是一個指針.
重點在於模板參數N能自動推導傳入數組的大小.
同樣我們可以將strcmp
做一個封裝, 實現一個字符串比較的模板函數.
template<unsigned N, unsigned M>
bool compare(const char (&a)[N], const char (&b)[M])
{
return strcmp(a, b);
}
總結
使用template
的非類型參數可以自動幫我們獲取參數的大小, 省去手動傳入參數大小的麻煩等問題. 記住 : 非類型模板參數在編譯期間就已經實例化, 所以其模板實參必須是常量表達式.