用户定义字面量

用户定义字面量（user-defined literal）是C++程序设计语言从C++11标准开始支持的用户定义类型的字面量。

背景

传统的C/C++提供了多种字面量。例如，“12.5”是一个字面量，被编译器当作double类型且值为12.5。如果增加后缀“f”，则“12.5f”就是float类型且值为12.5。字面量的后缀是由C/C++标准规定的，程序不能增加新的字面量类型或其后缀。
C++11增加了用户自行定义新的字面量后缀并由此用字面量构造对象的能力。这是通过定义字面量运算符（literal operator）函数或函数模板实现。该运算符名字由一对相邻双引号前导。字面量运算符通常在用户定义字面量的地方被隐式调用。例如，
#include<iostream>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;}

原始形式字面量

用户定义字面量的原始形式示例如下：
OutputType operator "" _suffix(const char * literal_string); //声明用户定义字面量的处理函数OutputType some_variable = 1234_suffix; //使用用户定义字面量
原始字面量运算符（raw literal operator）只能有单个参数，参数类型为const char * 。
处理整型或浮点型的用户定义原始形式字面量可以选择使用可变参数模板：
template<char...> OutputType operator "" _tuffix(); //声明函数模板OutputType some_variable = 1234_tuffix;   //使用OutputType another_variable = 2.17_tuffix;//使用
字面量运算符模板（literal operator template）的函数形参表必须为空；模板形参表只能有一个成员，即非类型的模板参数包（non-type template paremeter pack），其成员类型为char。
例如，上例中的字面量处理运算符函数模板被实例化为operator "" _tuffix<'1', '2', '3', '4'>()。这种情形下，没有字符串终止的null字符。这种形式的目的是使用C++11新增加的constexpr关键字，允许字面量在编译期被正确处理，这必须满足OutputType类型是常量表达式可构造（constexpr-constructable）与可复制（copyable）的，且字面量运算符函数（模板）是constexpr的。
例如：
#include<iostream>#include<string>using namespace std;struct S{
    S (const char * lls): value(lls){};
    string value;};template < char ... cdots> S operator "" _mysuffix(){
    const char cv[] {cdots...,'\0'}; //把可变的模板参数用于初始化器（initializer）
    S  sv_(cv);
    return sv_;}int main(){
   S sv {1234.567_mysuffix} ;
   std::cout<<sv.value<<std::endl;
   return 0;}

加工后形式的用户定义字面量

加工后形式的数值字面量所采用的类型，对于整型字面量是unsigned long long，对于浮点型字面量是long double。
不需要有符号的整型，因为整型字面量的符号前缀被分析（parse）为一个包含了作为酉前缀运算符（unary prefix operator）的表达式。
例如：
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字符的长度。字符串字面量没有可选的模板函数实现。

字符字面量

字符字面量可类似于字符串字面量那样定义与使用。 例如：
#include<iostream>#include<string>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;}