我正在查看cppreference page for user defined文字,除了一些例子,我想我理解了所有内容
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
上述两个功能有什么区别?如果第一个函数不是错误,那么调用第一个函数而不是第二个函数会有什么不同?
谢谢!
答案 0 :(得分:6)
template <char...> double operator "" _π(); // OK
此操作符如何工作?你怎么称呼它?
1.234_π
会致电operator "" _π<'1', '.', '2', '3', '4'>()
。此表单允许您检测通常无法检测到的拼写差异(例如1.2
与1.20
),并允许您避免由于1.2
无法准确表示而导致的舍入问题甚至是long 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
成为独立标记的原因,使其无法被视为用户定义的文字后缀。< / p>
为了便于编码,在定义这些函数时通常允许"" _Z
和""_Z
语法,但"" _Z
语法要求将_Z
视为标识符。当实现将_Z
预定义为宏或将其声明为自定义关键字时,这可能会导致问题。
答案 1 :(得分:1)
据我所知,两种签名之间没有区别。
问题是标准_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 "" _π();
或许请查看this.