目前一般所使用的 C++ 語法標準,實際上大部分應該都是俗稱 C++98 / C++03 的 ISO/IEC 14882:1998、ISO/IEC 14882:2003;其中 C++03 主要是針對 C++98 做部分修正,變化並不大(微軟 VC++ team 的 說法:C++03 只是 C++98 的「Service pack」)。那 C++ 有打算再有追加新功能嗎?實際上,目前也有還在規畫中、沒有正式定案的 C++0x 草案了!(詳細可以參考維基百科上的 C++ / C++0x 的條目)
而隨著新版 GCC(4.4/4.5)和 Visual Studio 2010 的推出,程式開發者也可以開始使用 C++0x 裡的部分新功能了!不過由於實際上 C++0x 是還沒正式定案的標準,所以其實不管是最新的 GCC 或 Visual C++ 2010,也都還沒有能完全支援 C++0x 的全部功能;實際上 C++0x 的規格也還在變動中,像 concepts 就被廢掉了。
Heresy 這一篇,主要會是以 Microsoft Visual C++ 2010 為主,介紹一些新的 C++0x 的語法;而 GCC 不同版本對 C++0x 的支援性,則建議可以參考官方的《C++0x Support in GCC》一文(用 g++ 編譯時需加上「-std=c++0x」這個參數)。
以 Visual C++ 2010 來說,他的新功能可以參考《What’s New in Visual C++ 2010》,而 C++0x 的部分則可以參考 VC++ 的 team blog 的《C++0x Core Language Features In VC10: The Table》一文;整體來說,VC++ 2010 的 C++0x 的新功能主要包括了六部份:
-
auto:《C++0x: auto 和 decltype》[MSDN]
-
自動根據 initialization expression 來判斷變數的型別,可以用來簡化較複雜的型別的變數的宣告;另外,也可以搭配新的 decltype 和 lambda expression 來做更多的應用。
-
下面就是一個簡單的範例。在編寫程式的時候,如果直接用「auto」來取代「map<int,list<string>>::iterator」的話,就可以少打不少字。
map<int,list<string>>::iterator i = m.begin(); auto i = m.begin();
-
-
decltype:《C++0x: auto 和 decltype》[MSDN]
-
decltype 是用來指定變數的型別的(Type Specifier),不過他所宣告的變數型別則是根據現有的變數、或是函式來做判斷。而如果搭配 auto 使用的話,可以更方便地編寫 template function。
-
下方是一個簡單的範例,透過這樣的 decltype 寫法,可以宣告出一個和 a 同型別的變數 b。
int a; decltype( a ) b;
-
-
Lambda Expressions:《C++0x:Lambda expression》[MSDN]
-
Lambda expression 基本上算是「匿名函式 (anonymous function)」,他可以快速地建立一個沒有名稱的 function object,避免掉 function object 要定義出一個 class / struct 的繁瑣工作。
-
他的語法可以參考《Lambda Expression Syntax》一文,而他比較基本的形式大致會是像下方的樣子;他傳入的參數是一個 int、而回傳值的型別(-> int)也是 int:
[] ( int x ) -> int { return x * x; }
-
下方是一個在使用 for_each() 時,使用 lambda expression 和 function object 的對照;在這種情況下使用 lambda expression 的話,程式碼可以簡化許多(不用定義出 LambdaFunctor 這個 class):
-
使用 function object
class LambdaFunctor { public: void operator()(int n) const { cout << n << " "; } }; int main() { vector<int> v; for( int i = 0; i < 10; ++i ) v.push_back(i); for_each( v.begin(), v.end(), LambdaFunctor() ); cout << endl; }
-
使用 lambda expression
int main() { vector<int> v; for (int i = 0; i < 10; ++i) v.push_back(i); for_each(v.begin(), v.end(), [](int n) { cout << n << " "; }); cout << endl; }
-
-
-
Rvalue Reference:[MSDN]
-
這部分主要要先搞清楚 C++ 裡的 Lvalues (left value) 和 Rvalues (right value) 的意義了。而 RValue reference 主要則是可以用來實作所謂的「move semantics」和「perfect forwarding」了~
-
-
static_assert:《C++0x:static_assert 和 nullptr》[MSDN]
-
這個功能可以讓編譯器在編譯時取做一些條件判斷,並且讓編譯失敗、並且顯示自定義的錯誤訊息。
-
下面是一個簡單的範例:
static_assert( sizeof(void *) == 4, "64bit is not supported.");
-
-
nullptr:《C++0x:static_assert 和 nullptr》[MSDN]
-
nullptr 是一個新的關鍵字,用來代表 NULL 指標的值;而本來在 C++03 / C99 裡,這個角色是由 0 來做的(NULL 實際上是 define 成 0 的 macro),但是這樣的缺點是無法區分 0 和 NULL 指標,在有的時後會產生 overloaded function 無法判斷的問題。所以在 C++0x 裡另外定義了 nullptr,來和 0 做區隔。
-
而這邊只是先針對這些新的功能做一些簡單的介紹,之後會在針對一些功能,做更完整的介紹。
另外,《Visual Studio 2010 Released》一文有大致條列出 Visual Studio 2010 的新功能,對於 Visual Studio 2010 的其他部分有興趣的,建議可以參考看看。
參考資料:
[…] C++11 引進的 std::tuple […]
讚讚
[…] Heresy 曾經寫過一篇《C++11 的「…」:Parameter Pack》,算是簡單介紹了 C++11 新增的 「parameter […]
讚讚
[…] C++11 加入、代表特定大小的整數型別(Fixed width integer […]
讚讚
[…] 應該是大家都熟系的老標準就有的,constexpr 則是在 C++11 的時候加入的;consteval 和 constinit 則是 C++20 […]
讚讚
[…] C++11 時加入的 std::get_time() […]
讚讚
[…] C++11 開始、到現在的 C++20,一些針對 C++ […]
讚讚
[…] move 的形式,他還是弊免不了會產生一個臨時物件。為了解決這個問題,C++11 […]
讚讚
[…] C++11 應該算是 C++ 改變最大的版本,而針對 C++11 的東西其實 Heresy 已經寫了不少了,但是實際上還是沒有能把想記錄的東西都寫過一遍。 […]
讚讚
[…] C++11 所推出的 Lambda expression 這種匿名函式,Heresy 一開始還覺得不知道哪裡可以用?但是後來真正寫多了,才發現他實際上是非常好用的一個功能。 […]
讚讚