使用者定義字面量

使用者定義字面量是C++程式設計語言從C++11標準開始支援的使用者定義型別的字面量。背景.傳統的C/C++提供了多種字面量。例如，“codice_1”是一個字面量，被編譯器當作codice_2型別且值為12.5。如果增加字尾“codice_3”，則“codice_4”就是codice_5型別且值為12.5。字面量的字尾是由C/C++標準規定的，程式不能增加新的字面量型別或其後綴。C++11增加了使用者自行定義新的字面量字尾並由此用字面量構造物件的能力。這是透過定義字面量運算子函式或函式模板實現。該運算子名字由一對相鄰雙引號前導。字面量運算子通常在使用者定義字面量的地方被隱式呼叫。例如，struct S{int value;S operator ""_mysuffix(unsigned long long v) //使用者定義字面量運算子的實現S s_;s_.value=(int)v;return s_;int main()S sv;sv=101_mysuffix; //這裡的101是型別S的字面量std::cout«sv.value«std::endl;return 0;簡介.使用者定義字面量分為四類：編譯器對源程式做詞法分析時自動判決當前的使用者定義字面量屬於哪一類，然後根據字面量字尾識別符號，隱式呼叫相應的字面量運算子函式或模板函式，建構出相應型別的物件例項。使用者字面量運算子的宣告、定義，可以放在名字空間中以避免名字的衝突。編譯器做字面量變換分為兩個階段：原始。原始字面量是特定型別的字元的序列。加工後字面量是單獨的型別。例如：C++字面量codice_6，作為原始字面量是字元序列codice_7, codice_8, codice_9, codice_10；作為加工後字面量是整數1234。C++字面量codice_11的原始形式是codice_12, codice_13, codice_14，加工後形式為整數10。字面量既可以用原始形式也可以用加工後形式擴充套件。但字串字面量只能以加工後形式處理，因為字串可以有字首影響了字元的意義與型別。例如字首為‘L’，表示寬字元。所有使用者定義字面量只能使用字尾。以下劃線符號(codice_15) 以外的任何字元開始的字面量字尾都被C++標準保留。因此，所有使用者定義的字面量都應該以下劃線符號(codice_15) 為字尾開始字元。原始形式字面量.使用者定義字面量的原始形式示例如下：OutputType operator "" _suffix(const char * literal_string); //宣告使用者定義字面量的處理函式OutputType some_variable = 1234_suffix; //使用使用者定義字面量原始字面量運算子只能有單個引數，引數型別為codice_17。處理整型或浮點型的使用者定義原始形式字面量可以選擇使用可變引數模板：template OutputType operator "" _tuffix(); //宣告函式模板OutputType some_variable = 1234_tuffix; //使用OutputType another_variable = 2.17_tuffix;//使用字面量運算子模板，其成員型別為codice_18。例如，上例中的字面量處理運算子函式模板被例項化為codice_19。這種情形下，沒有字串終止的null字元。這種形式的目的是使用C++11新增加的codice_20關鍵字，允許字面量在編譯期被正確處理，這必須滿足codice_21型別是常量表達式可構造是codice_20的。例如：using namespace std;struct S{S (const char * lls): value(lls){};string value;template  S operator "" _mysuffix()const char cv[] {cdots...,'\0'}; //把可變的模板引數用於初始化器S sv_(cv);return sv_;int main()S sv {1234.567_mysuffix} ;std::cout«sv.value«std::endl;return 0;加工後形式的使用者定義字面量.加工後形式的數值字面量所採用的型別，對於整型字面量是codice_23，對於浮點型字面量是codice_24。不需要有符號的整型，因為整型字面量的符號字首被分析的表示式。例如：OutputType operator "" _suffix(unsigned long long);OutputType operator "" _suffix(long double);OutputType some_variable = 1234_suffix; // Uses the 'unsigned long long' overload.OutputType another_variable = 3.1416_suffix; // Uses the 'long double' overload.字串字面量.對於字串字面量，可使用下述形式，並可配合C++11的幾種字串字首：OutputType operator "" _ssuffix(const char * string_values, size_t num_chars);OutputType operator "" _ssuffix(const wchar_t * string_values, size_t num_chars);OutputType operator "" _ssuffix(const char16_t * string_values, size_t num_chars);OutputType operator "" _ssuffix(const char32_t * string_values, size_t num_chars);OutputType some_variable = "1234"_ssuffix; // Uses the 'const char *' overload.OutputType some_variable = u8"1234"_ssuffix; // Uses the 'const char *' overload.OutputType some_variable = L"1234"_ssuffix; // Uses the 'const wchar_t *' overload.OutputType some_variable = u"1234"_ssuffix; // Uses the 'const char16_t *' overload.OutputType some_variable = U"1234"_ssuffix; // Uses the 'const char32_t *' overload.上述字串字面量運算子函式的第二個引數表示字串不包括尾null字元的長度。字串字面量沒有可選的模板函式實現。字元字面量.字元字面量可類似於字串字面量那樣定義與使用。 例如：using namespace std;struct S{S (const char * lls): value(lls){};string value;S operator "" _mysuffix(const char * string_values, size_t num_chars) //字串字面量S sv_ (string_values);return sv_;S operator "" _mysuffix(char value) //字元字面量const char cv[] {value,'\0'};S sv_ (cv);return sv_;int main()S sv {"hello"_mysuffix} ;std::cout«sv.value«std::endl;S cv {'h'_mysuffix} ;std::cout«cv.value«std::endl;return 0;C++標準中的幾個使用者定義字面量.C++11引入了使用者定義字面量字尾的語法，但標準庫沒有使用任何此類東西。C++14標準增加了下述的字面量字尾：string str = "hello world"s;chrono::duration dur = 60s;例子中的兩個"s"作為字面量字尾並不一樣，因為前者用於字串字面量，後者用於數值字面量。