字面量运算符/字面量操作符

起因:

在阅读cpp-httplib源码时看到下边这段代码

inline constexpr unsigned int operator"" _t(const char *s, size_t l) {
  return str2tag_core(s, l, 0);
}

以及他的运用

"css"_t

第一次见到这种写法,由于operator是运算符重载,猜测是重载某种类型的运算符,查到这种叫做“字面量运算符”,具体可以参考下边这篇文章
C++操作符重载总结、字面量运算符
在这里根据查到的资料做一下总结和example

概念:

  1. 定义形式 :形如T operator"" name(T1, T2),其中name是用户自定义的后缀,例如unsigned int operator“” _t(const char*s, size_t l),用的话这样使用"123"_t。一般建议后缀开头是下划线。
  2. 字面量重载运算符可以把字面值常量,(注意只能是字面值常量,也就是“123”,123,1.23,‘a’这样,不能是变量。),转化为需要的类型对象。
  3. 注意字面值常量不能是成员函数。

使用要点:根据字面值类型的不同,操作符函数可以接受的参数也是不一样的。

  1. 字面值是整数:操作符只能接受unsigned long long 或者 const char*作为参数。
  2. 字面量为浮点数,操作符函数只可接受 long double 或者 const char* 为参数。
  3. 字面量为字符串,操作符函数只可接受 const char*,size_t为参数。
  4. 字面量为字符,则操作符函数只接受一个 char 为参数。

例如:

  1. 整数
int operator"" _n(unsigned long long i){
    return i / 10;
}
void test_n(){
    int a = -21474836470_n;
    cout << a << endl;
}

并不会出现溢出,并且和直接调用n还不一样,似乎不是把a转换成unsignde long long之后进行计算,也会考虑本身的符号。
可能是在计算的时候先不考虑符号,计算完再把符号填上去,毕竟这个是字面值运算符,完全可以放在编译期间运算。

  1. 浮点数
double operator"" _f(long double i){
    return i / 10;
}
void test_f(){
    double a = -214748.36470_f;
    cout <<  a << endl;
}c
  1. 字符串
unsigned int operator"" _s(const char*s, size_t l){
    cout << "s = " << s << endl << "l = " << l << endl;
    return l;
}
void test_s(){
    unsigned int a = "12346"_s;
    cout << a << endl;
}
  1. 字符
int operator"" _c(char c){
    return c;
}
void test_c(){
    cout << 'a'_c << ", " << 'A'_c << endl;

}

用处:简化操作

冷门玩意: C++字面量运算符重载

#include 
#include 
#include 

struct YYYYMMDD
{
    int yyyy;
    int mm;
    int dd;
};


YYYYMMDD operator "" _yyyymmdd( const char * ymd_str, std::size_t ymd_size)
{
    if (ymd_size<8)
    {
        throw std::invalid_argument( "invalid ymd string:"+std::string(ymd_str));
    }

    YYYYMMDD ymd_struct;
    ymd_struct.yyyy = (ymd_str[0]-'0')*1000+(ymd_str[1]-'0')*100+(ymd_str[2]-'0')*10+(ymd_str[3]-'0');
    ymd_struct.mm = (ymd_str[4]-'0')*10+(ymd_str[5]-'0');
    ymd_struct.dd = (ymd_str[6]-'0')*10+(ymd_str[7]-'0');
    return ymd_struct;
}

YYYYMMDD operator "" _yyyymmdd(unsigned long long int ymd_num)
{
    if(ymd_num<10000000 || ymd_num>30000000)
    {
        throw std::invalid_argument( "invalid ymd num:"+ymd_num);
    }
    YYYYMMDD ymd_struct;
    ymd_struct.yyyy = ymd_num/10000;
    ymd_struct.mm = (ymd_num%ymd_struct.yyyy)/100;
    ymd_struct.dd = ymd_num%ymd_struct.yyyy%ymd_struct.mm;
    return ymd_struct;
}

int main()
{
    auto ymd_struct = 20001101_yyyymmdd;
    std::cout<<"year:"<<ymd_struct.yyyy<<std::endl;
    std::cout<<"month:"<<ymd_struct.mm<<std::endl;
    std::cout<<"day:"<<ymd_struct.dd<<std::endl;

    auto ymd_struct1 = "20001101"_yyyymmdd;
    std::cout<<"year:"<<ymd_struct1.yyyy<<std::endl;
    std::cout<<"month:"<<ymd_struct1.mm<<std::endl;
    std::cout<<"day:"<<ymd_struct1.dd<<std::endl;
    return 0;
}

你可能感兴趣的:(c++)