fbpx
维基百科

用户定义字面量

用户定义字面量(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)函数或函数模板实现。该运算符名字由一对相邻双引号前导。[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++字面量1234,作为原始字面量是字符序列'1', '2', '3', '4';作为加工后字面量是整数1234。C++字面量0xA的原始形式是'0', 'x', 'A',加工后形式为整数10。

字面量既可以用原始形式也可以用加工后形式扩展。但字符串字面量只能以加工后形式处理,因为字符串可以有前缀影响了字符的意义与类型。例如前缀为‘L’,表示宽字符。

所有用户定义字面量只能使用后缀。以下划线符号(_) 以外的任何字符开始的字面量后缀都被C++标准保留。因此,所有用户定义的字面量都应该以下划线符号(_) 为后缀开始字符。

原始形式字面量 编辑

用户定义字面量的原始形式示例如下:

OutputType operator "" _suffix(const char * literal_string); //声明用户定义字面量的处理函数 OutputType some_variable = 1234_suffix; //使用用户定义字面量 

原始字面量运算符(raw literal operator)只能有单个参数,参数类型为const char * [3]

处理整型或浮点型的用户定义原始形式字面量可以选择使用可变参数模板

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[4]

例如,上例中的字面量处理运算符函数模板被实例化为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; } 

C++标准中的几个用户定义字面量 编辑

C++11引入了用户定义字面量后缀的语法,但标准库没有使用任何此类东西。C++14标准增加了下述的字面量后缀:

  • "s",用于结合字符串前缀创建各类std::basic_string字面量;
  • "h", "min", "s", "ms", "us", "ns", 用于创建对应的std::chrono::duration时间间隔。例如:
string str = "hello world"s; chrono::duration dur = 60s; 

例子中的两个"s"作为字面量后缀并不一样,因为前者用于字符串字面量,后者用于数值字面量。[5]

参考文献 编辑

  1. ^ C++11 13.5.8
  2. ^ C++11 2.14.8
  3. ^ C++11 13.5.8 - 4
  4. ^ C++11 13.5.8 - 5
  5. ^ Peter, Sommerlad. N3642 User-defined Literals for Standard Library Types (part 1 - version 4) (PDF). 18 April 2013 [2015-01-02]. (原始内容 (PDF)于2021-03-08). 

用户定义字面量, user, defined, literal, 是c, 程序设计语言从c, 11标准开始支持的用户定义类型的字面量, 目录, 背景, 简介, 原始形式字面量, 加工后形式的, 字符串字面量, 字符字面量, 标准中的几个, 参考文献背景, 编辑传统的c, 提供了多种字面量, 例如, 是一个字面量, 被编译器当作double类型且值为12, 如果增加后缀, 就是float类型且值为12, 字面量的后缀是由c, 标准规定的, 程序不能增加新的字面量类型或其后缀, 11增加了用户自行定义新的字面量后缀并由. 用户定义字面量 user defined literal 是C 程序设计语言从C 11标准开始支持的用户定义类型的字面量 目录 1 背景 2 简介 2 1 原始形式字面量 2 2 加工后形式的用户定义字面量 2 3 字符串字面量 2 4 字符字面量 3 C 标准中的几个用户定义字面量 4 参考文献背景 编辑传统的C C 提供了多种字面量 例如 12 5 是一个字面量 被编译器当作double类型且值为12 5 如果增加后缀 f 则 12 5f 就是float类型且值为12 5 字面量的后缀是由C C 标准规定的 程序不能增加新的字面量类型或其后缀 C 11增加了用户自行定义新的字面量后缀并由此用字面量构造对象的能力 这是通过定义字面量运算符 literal operator 函数或函数模板实现 该运算符名字由一对相邻双引号前导 1 字面量运算符通常在用户定义字面量的地方被隐式调用 例如 include lt iostream gt 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 lt lt sv value lt lt std endl return 0 简介 编辑用户定义字面量分为四类 2 数值型字面量 整数型字面量 浮点型字面量 字符串字面量 字符字面量编译器对源程序做词法分析时自动判决当前的用户定义字面量属于哪一类 然后根据字面量后缀标识符 隐式调用相应的字面量运算符函数或模板函数 建构出相应类型的对象实例 用户字面量运算符的声明 定义 可以放在名字空间 namespace 中以避免名字的冲突 编译器做字面量变换分为两个阶段 原始 raw 与加工后 cooked 原始字面量是特定类型的字符的序列 加工后字面量是单独的类型 例如 C 字面量1234 作为原始字面量是字符序列 1 2 3 4 作为加工后字面量是整数1234 C 字面量0xA的原始形式是 0 x A 加工后形式为整数10 字面量既可以用原始形式也可以用加工后形式扩展 但字符串字面量只能以加工后形式处理 因为字符串可以有前缀影响了字符的意义与类型 例如前缀为 L 表示宽字符 所有用户定义字面量只能使用后缀 以下划线符号 以外的任何字符开始的字面量后缀都被C 标准保留 因此 所有用户定义的字面量都应该以下划线符号 为后缀开始字符 原始形式字面量 编辑 用户定义字面量的原始形式示例如下 OutputType operator suffix const char literal string 声明用户定义字面量的处理函数 OutputType some variable 1234 suffix 使用用户定义字面量 原始字面量运算符 raw literal operator 只能有单个参数 参数类型为const char 3 处理整型或浮点型的用户定义原始形式字面量可以选择使用可变参数模板 template lt char gt OutputType operator tuffix 声明函数模板 OutputType some variable 1234 tuffix 使用 OutputType another variable 2 17 tuffix 使用 字面量运算符模板 literal operator template 的函数形参表必须为空 模板形参表只能有一个成员 即非类型的模板参数包 non type template paremeter pack 其成员类型为char 4 例如 上例中的字面量处理运算符函数模板被实例化为operator tuffix lt 1 2 3 4 gt 这种情形下 没有字符串终止的null字符 这种形式的目的是使用C 11新增加的constexpr关键字 允许字面量在编译期被正确处理 这必须满足OutputType类型是常量表达式可构造 constexpr constructable 与可复制 copyable 的 且字面量运算符函数 模板 是constexpr的 例如 include lt iostream gt include lt string gt using namespace std struct S S const char lls value lls string value template lt char cdots gt S operator mysuffix const char cv cdots 0 把可变的模板参数用于初始化器 initializer S sv cv return sv int main S sv 1234 567 mysuffix std cout lt lt sv value lt lt 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 lt iostream gt include lt string gt 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 lt lt sv value lt lt std endl S cv h mysuffix std cout lt lt cv value lt lt std endl return 0 C 标准中的几个用户定义字面量 编辑C 11引入了用户定义字面量后缀的语法 但标准库没有使用任何此类东西 C 14标准增加了下述的字面量后缀 s 用于结合字符串前缀创建各类std basic string字面量 h min s ms us ns 用于创建对应的std chrono duration时间间隔 例如 string str hello world s chrono duration dur 60 s 例子中的两个 s 作为字面量后缀并不一样 因为前者用于字符串字面量 后者用于数值字面量 5 参考文献 编辑 C 11 13 5 8 C 11 2 14 8 C 11 13 5 8 4 C 11 13 5 8 5 Peter Sommerlad N3642 User defined Literals for Standard Library Types part 1 version 4 PDF 18 April 2013 2015 01 02 原始内容存档 PDF 于2021 03 08 取自 https zh wikipedia org w index php title 用户定义字面量 amp oldid 69710736, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。