用户定义字面量用户定义字面量(user-defined literal)是C++程序设计语言从C++11标准开始支持的用户定义类型的字面量。 背景传统的C/C++提供了多种字面量。例如,“ C++11增加了用户自行定义新的字面量后缀并由此用字面量构造对象的能力。这是通过定义字面量运算符(literal operator)函数或函数模板实现。该运算符名字由一对相邻双引号前导。[1]字面量运算符通常在用户定义字面量的地方被隐式调用。例如, #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;
}
简介用户定义字面量分为四类:[2]
编译器对源程序做词法分析时自动判决当前的用户定义字面量属于哪一类,然后根据字面量后缀标识符,隐式调用相应的字面量运算符函数或模板函数,建构出相应类型的对象实例。 用户字面量运算符的声明、定义,可以放在名字空间(namespace)中以避免名字的冲突。 编译器做字面量变换分为两个阶段:原始(raw)与加工后(cooked)。原始字面量是特定类型的字符的序列。加工后字面量是单独的类型。例如:C++字面量 字面量既可以用原始形式也可以用加工后形式扩展。但字符串字面量只能以加工后形式处理,因为字符串可以有前缀影响了字符的意义与类型。例如前缀为‘L’,表示宽字符。 所有用户定义字面量只能使用后缀。以下划线符号( 原始形式字面量用户定义字面量的原始形式示例如下: OutputType operator "" _suffix(const char * literal_string); //声明用户定义字面量的处理函数
OutputType some_variable = 1234_suffix; //使用用户定义字面量
原始字面量运算符(raw literal operator)只能有单个参数,参数类型为 处理整型或浮点型的用户定义原始形式字面量可以选择使用可变参数模板: template<char...> OutputType operator "" _tuffix(); //声明函数模板
OutputType some_variable = 1234_tuffix; //使用
OutputType another_variable = 2.17_tuffix;//使用
字面量运算符模板(literal operator template)的函数形参表必须为空;模板形参表只能有一个成员,即非类型的模板参数包(non-type template paremeter pack),其成员类型为 例如,上例中的字面量处理运算符函数模板被实例化为 例如: #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;
}
加工后形式的用户定义字面量加工后形式的数值字面量所采用的类型,对于整型字面量是 不需要有符号的整型,因为整型字面量的符号前缀被分析(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;
}
C++标准中的几个用户定义字面量C++11引入了用户定义字面量后缀的语法,但标准库没有使用任何此类东西。C++14标准增加了下述的字面量后缀:
string str = "hello world"s;
chrono::duration dur = 60s;
例子中的两个"s"作为字面量后缀并不一样,因为前者用于字符串字面量,后者用于数值字面量。[5] 参考文献 |
Portal di Ensiklopedia Dunia