歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網

C++11 FAQ

日期:2017/3/1 9:38:05   编辑:Linux編程
auto – 從初始化中推斷數據類型 當數據類型未知或不便書寫時,使用auto可讓編譯器自動根據用以初始化變量的表達式類型來推導變量類型。考慮如下代碼:
template<class T > void printall(const vector< T>& v) { // 根據v.begin()的返回值類型自動推斷p的數據類型 for ( auto p = v.begin(); p != v.end(); ++p) cout << *p << “n”; }
枚舉類——具有類域和強類型的枚舉 枚舉類主要用來解決傳統的C++枚舉的三個問題:
  • 傳統C++枚舉會被隱式轉換為int,這在那些不應被轉換為int的情況下可能導致錯誤
  • 傳統C++枚舉的每一枚舉值在其作用域范圍內都是可見的,容易導致名稱沖突(同名沖突)
  • 不可以指定枚舉的底層數據類型,這可能會導致代碼不容易理解、兼容性問題以及不可以進行前向聲明
enum Alert { green , yellow , election , red }; // 傳統枚舉
enum class Color { red, blue }; // 新的具有類域和強類型的枚舉類
// 它的枚舉值在類的外部是不可直接訪問的,需加“類名::”
// 不會被隱式轉換成int
enum class TrafficLight { red , yellow , green };
Alert a = 7; // 錯誤,傳統枚舉不是強類型的,a沒有數據類型
Color c = 7; // 錯誤,沒有int到Color的隱式轉換
int a2 = red; // 正確,Alert被隱式轉換成int
int a3 = Alert:: red; // 在 C++98中是錯誤的,但是在C++11中正確的
int a4 = blue; // 錯誤,blue並沒有在類域中
int a5 = Color:: blue; // 錯誤,沒有Color到int的默認轉換 Color a6 = Color:: blue; // 正確 正如上面的代碼所展示的那樣,傳統的枚舉可以照常工作,但是你現在可以通過提供一個類名來改善枚舉的使用,使其成為一個強類型的具有類域的枚舉。因為新的具有類名的枚舉具有傳統的枚舉的功能(命名的枚舉值),同時又具有了類的一些特點(枚舉值作用域處於類域之內且不會被隱式類型轉換成int),所以我們將其稱為枚舉類(enum class)。 因為可以指定枚舉的底層數據類型,所以可以進行簡單的互通操作以及保證枚舉值所占的字節大小:
enum class Color : char { red , blue }; // 緊湊型表示(一個字節) enum EE : unsigned long { EE1 = 1, EE2 = 2, EEbig = 0xFFFFFFF0U }; // C11中我們可以指定枚舉值的底層數據類型大小
同時,由於能夠指定枚舉值的底層數據類型,所以前向聲明得以成為可能:
enum class Color_code : char ; // (前向) 聲明 void foobar(Color_code * p); // 使用 // ... // 定義 enum class Color_code : char { red , yellow , green , blue };
常量表達式(constexpr) — 一般化的受保證的常量表達式 常量表達式機制是為了:
  • 提供一種更加通用的常量表達式
  • 允許用戶自定義的類型成為常量表達式
  • 提供了一種保證在編譯期完成初始化的方法(可以在編譯時期執行某些函數調用)

考慮下面這段代碼: enum Flags { good = 0, fail = 1, bad = 2, eof = 4 };
constexpr int operator|( Flags f1, Flags f2)
{
return Flags( int( f1) | int( f2));
}
void f( Flags x)
{
switch ( x) {
case bad: /* … */ break ;
case eof: /* … */ break ;
case bad | eof: /* … */ break ;
default: /* … */ break ;
}
} 在這裡,常量表達式關鍵字constexpr表示這個重載的操作符“|”只應包含形式簡單的運算,如果它的參數本身就是常量 ,那麼這個操作符應該在編譯時期就應該計算出它的結果來。(譯注: 我們都知道,switch的分支條件要求常量,而使用constexpr關鍵字重載操作符“|”之後,雖然“bad|eof”是一個表達式,但是因為這兩個參數都是常量,在編譯時期,就可以計算出它的結果,因而也可以作為常量對待。) 除了可以在編譯時期被動地計算表達式的值之外,我們希望能夠強制要求表達式在編譯時期計算其結果值,從而用作其它用途,比如對某個變量進行賦值。當我們在變量聲明前加上constexpr關鍵字之後,可以實現這一功能,當然,它也同時會讓這個變量成為常量。 constexpr int x1 = bad | eof; // ok void f(Flags f3) { // 錯誤:因為f3不是常量,所以無法在編譯時期計算這個表達式的結果值 constexpr int x2 = bad | f3; int x3 = bad | f3; // ok,可以在運行時計算 }

需要注意的是,constexpr並不是const的通用版,反之亦然:

  • const主要用於表達“對接口的寫權限控制”,即“對於被const修飾的量名(例如const指針變量),不得通過它對所指對象作任何修改”。(但是可以通過其他接口修改該對象)。另外,把對象聲明為const也為編譯器提供了潛在的優化可能。具體來說就是,如果把一個量聲明為const,並且沒有其他地方對該量作取址運算,那麼編譯器通常(取決於編譯期實現)會用該量的實際常量值直接替換掉代碼中所有引用該量的地方,而不用在最終編譯結果中生成對該量的存取指令。
  • constexpr的主要功能則是讓更多的運算可以在編譯期完成,並能保證表達式在語義上是類型安全的。(譯注:相比之下,C語言中#define只能提供簡單的文本替換,而不具任何類型檢查能力)。與const相比,被constexpr修飾的對象則強制要求其初始化表達式能夠在編譯期完成計算。之後所有引用該常量對象的地方,若非必要,一律用計算出來的常量值替換。

C++11新特性:Lambda函數(匿名函數) http://www.linuxidc.com/Linux/2013-12/93367p2.htm

C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm

讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm

讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm

C++11 獲取系統時間庫函數 time since epoch http://www.linuxidc.com/Linux/2014-03/97446.htm

C++11中正則表達式測試 http://www.linuxidc.com/Linux/2012-08/69086.htm

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-10/108758p2.htm

Copyright © Linux教程網 All Rights Reserved