C++的那些事 1
最近在看c++的一些庫檔案,裡面的一些比較陌生但看起來挺有用的一些東西,在此記下,以免日後看到再翻找資料。
template <size_t _Nb>
這是在看bitset的時候看到的,之前用bitset的時候也沒太留意,這是才發現bitset的類模板引數不是一個型別,而是一個數,這才發現原來類模板引數也可以是一個數。
在C++ Primer
的654頁提到了Nontype Template Parameters就是指這個,來看一下他給的例子。
template <unsigned N, unsigned M> int compare(const char (&p1)[N], const char (&p2)[M]) { return strcmp(p1, p2); }
當我們呼叫
compare("hi", "mom");
相當於是呼叫了
int compare(const char (&p1)[3], const char (&p2)[4])
也就是說Nontype Template Parameters跟我們平常所用的模板其實是類似的,只不過平常所用的模板引數是資料型別,而這個是數,bitset就是用這個來宣告bitset的位數。
這時,如果類中的一個常量成員與模板引數有關,那麼這個常量成員要設為靜態常量,因為對於同一個例項模板,這個成員是靜態的(不隨新建物件而改變)。
array
我們經常用new[]來新建一個數組,但這樣很容易出錯,如果不小心把頭指標弄丟了,那麼整個陣列就沒了,而且新建出來的記憶體也會浪費掉,所以C++11新添加了一個array的資料新型,新建以後就當陣列用就是了,而且與陣列一樣,它的記憶體儲存是連續的。
Rvalue Reference(右值引用)
bitset::insert(const_iterator position, value_type&& val)
上面程式碼中的value_type&& val
就是右值引用的一個例子,在C++ Primer
的532頁有關於Rvalue Reference
的介紹,這個的主要使用是在物件要被釋放之前將物件的資源(內容)移出來,而不是進行復制操作,就像原文所說的:
Rvalue reference refer to objects that are about to be destroyed. Hence, we can "steal" state from an object bound to an rvalue reference.
在平常的使用中可能沒有感受到右值引用帶來的好處,特別是對"steal"如何理解,我覺得知乎上Tinro的回答中對"steal"的解釋挺詳細的,通過右值引用這個概念可以進行很多優化。
Variadic Template
在看到這個的時候,我特別開心,因為我知道Matlab是有這個功能的,以前以為C++沒有這個功能,覺得怪可惜的,現在發現可以這樣用,而且與tuple配合使用可以產生許多好用的功能,舉個例子(C++ Primer
第700頁)
template <typename T, typename... Args>
void foo(const T &t, const Args&... rest);
這就是一個可變引數模板,其中Args是一個模板引數包,rest是一個函式引數包,因此foo函式的引數只要大於一個就行,下面是一些呼叫的例子
int i=0; double d=3.14; string s="variadic";
foo(i, s, 42, d); //包中有三個引數
foo(s, 42, "hi"); //包中有兩個引數
foo(d, s); //包中有一個引數
foo("hi"); //包中沒有引數
如果對rest進行取地址的處理,那麼得到的會是rest裡面所有變數都取地址,用cout輸出時,只需cout << rest
即可按順序輸出引數。
但如果要對引數進行運算,就要用到tuple
這一資料型別,tuple
的每個變數的型別都可以不一樣,支援取某個變數的型別,取值等操作,這樣只要把用(Args, rest)
新建一個tuple
,就可以對裡面的值進行修改。下面是tuple
的例子
tuple< string, vector<double>, int, list<int> > someVal("constants", {3.14, 2.718}, 42, {0,1, 2, 3, 4, 5});
typedef decltype(someVal) trans; //trans: <string, vector<double>, int, list<int> >
tuple_element<2, trans>::type cnt=get<2>(someVal);
//tuple_element<2, trans>::type :取trans中的第2個型別,get<1>(someVal) :取someVal中的第2個數。
//所以cnt的型別為int, 數值為42