4

我正在查看用户定义文字的 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

上面两个函数有什么区别?如果第一个不是错误,那么调用第一个函数与第二个函数有什么区别?

谢谢!

4

2 回答 2

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

这个运算符是如何工作的?你怎么称呼它?

1.234_π会打电话operator "" _π<'1', '.', '2', '3', '4'>()。这种形式允许您检测通常无法检测到的拼写差异(例如1.2vs 1.20),并允许您避免由于1.2在 even 中无法精确表示而导致的舍入问题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独立标记的组成部分,防止它被视为用户定义的文字后缀。

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

于 2017-01-21T22:52:13.467 回答
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 "" _π();Maybe 看看这个。

于 2017-01-21T22:06:13.080 回答