用户定义的文字定义

User defined literals definitions

本文关键字:定义 文字 用户      更新时间:2023-10-16

我在cppreference页面上查看了用户定义的文字,我想除了几个例子之外,我什么都懂了

template <char...> double operator "" _π(); // OK

这个操作员是如何工作的?你怎么称呼它?

double operator"" _Z(long double); // error: all names that begin with underscore
// followed by uppercase letter are reserved
double operator""_Z(long double); // OK: even though _Z is reserved ""_Z is allowed

以上两种功能之间的区别是什么?如果第一个函数不是错误,那么调用第一个函数与调用第二个函数有什么区别?

谢谢!

template <char...> double operator "" _π(); // OK

这个操作员是如何工作的?你怎么称呼它?

1.234_π将调用operator "" _π<'1', '.', '2', '3', '4'>()。此表单允许您检测通常无法检测到的拼写差异(例如,1.21.20),并允许您避免由于1.2long double中无法准确表示而导致的舍入问题。

double operator"" _Z(long double); // error: all names that begin with underscore
// followed by uppercase letter are reserved
double operator""_Z(long double); // OK: even though _Z is reserved ""_Z is allowed

以上两种功能之间的区别是什么?

C++标准用标记来定义语法,您可以将其解释为单词。"" _Z是两个令牌,""_Z""_Z是单个令牌。

这种区别很重要:给定#define S " world!",然后是"Hello" S,空白使S成为一个独立的标记,防止它被视为用户定义的文字后缀。

为了更容易编码,在定义这些函数时,通常允许使用"" _Z""_Z语法,但"" _Z语法要求将_Z视为标识符。当实现将_Z预定义为宏或将其声明为自定义关键字时,这可能会导致问题。

据我所知,这两个符号之间没有区别。

问题在于,标识符_Z在技术上由该标准保留。主要区别在于有一个空间:

double operator""/*space*/_Z(long double); 
double operator""_Z(long double); 

删除空间基本上是一种变通方法,理论上可以抑制错误(或者更可能是一种警告)。

至于你是如何使用它们的,你有没有看过你列出的链接中的例子?

#include <iostream>
// used as conversion
constexpr long double operator"" _deg ( long double deg )
{
return deg*3.141592/180;
}
// used with custom type
struct mytype
{
mytype ( unsigned long long m):m(m){}
unsigned long long m;
};
mytype operator"" _mytype ( unsigned long long n )
{
return mytype(n);
}
// used for side-effects
void operator"" _print ( const char* str )
{
std::cout << str;
}
int main(){
double x = 90.0_deg;
std::cout << std::fixed << x << 'n';
mytype y = 123_mytype;
std::cout << y.m << 'n';
0x123ABC_print;
}

用户定义的文字背后的思想是允许创建一个运算符,该运算符可以应用于可以将内置文字转换为另一种类型的内置类型。

编辑:

要调用其中一个运算符,只需要将该运算符作为后缀附加到值文字中。因此:

// used as conversion
constexpr long double operator"" _deg ( long double deg )
{
return deg*3.141592/180;
}

调用代码可以是例如:

long double d = 45_deg;

至于使用template <char...> double operator "" _π();,也许可以看看这个。