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


    起因:

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

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

    以及他的运用

    "css"_t
    
    • 1

    第一次见到这种写法,由于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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    并不会出现溢出,并且和直接调用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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 字符
    int operator"" _c(char c){
        return c;
    }
    void test_c(){
        cout << 'a'_c << ", " << 'A'_c << endl;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    用处:简化操作

    冷门玩意: 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
  • 相关阅读:
    【python脚本】用于生成简单握手接口与自测环境的gen_uvm_agent脚本
    HW-初始准备
    linux基本指令(二)
    AppLovin 175 亿美元收购游戏引擎Unity?
    Spring IOC之AdviceModeImportSelector
    480439-15-4,一种具有荧光单体的pH敏感性染料Fluorescein O-methacrylate
    KNN 算法【python,机器学习,算法】
    快手116购物节第四年,已成为电商领域大IP
    牵着她——表白代码(Python实现)
    数码3C零售门店运营,智慧显示有何优势?以清远电信为例。
  • 原文地址:https://blog.csdn.net/qq_42370809/article/details/126065543