zoukankan      html  css  js  c++  java
  • c++11: 用户定义字面量

    c++11带来了很多新特性,其中用户定义字面量就是一个。

    注:该特性vs2013不支持, vs2014和gcc4.9支持。这里推荐一个在线的c++编译网站,用来测试一些代码还是蛮有用的,并且它支持超多的语言像python、lua等都支持。网址在这里 http://ideone.com/

    先看下面的代码:

    #include <iostream>
    using namespace std;
    
    struct Color
    {
        int r, g, b;
    };
    
    //定义的字面量转换函数 
    //在gcc编译器下注意双引号与后面的_c之间必须有一个空格 vs2014没有该要求
    //_c可以任意取名字 一般最好用下划线(_)开头 避免与系统定义的冲突(比方说长整形后缀 L等))
    Color operator"" _c(const char* str, size_t n)
    {
        //字面常量格式为 r数字g数字b数字
        unsigned char r = 0, g = 0, b = 0;
        for (size_t i = 0; i < n; i++)
        {
            if (str[i] == 'r') r = (unsigned char)atoi(&str[i + 1]);
            else if (str[i] == 'g') g = (unsigned char)atoi(&str[i + 1]);
            else if (str[i] == 'b') b = (unsigned char)atoi(&str[i + 1]);
        }
        
        return {r, g, b};
    }
    
    int main() {
        //这样使用 将把“r11g12b13”转换成Color结构体 字符串必须用引号括起来 后面必须跟一个_c(前面自定义)的后缀 且与前面的字符串不予许有其他包括空格等字符
        Color c = "r11g12b13"_c;
        //输出结果是R11 G12 B13
        cout << "R" << c.r << " G" << c.g << " B" << c.b << endl;
        return 0;
    }

    以上是其中一种使用方法 我们来看另外一个例子 将说明这个特性的方便之处。

    比方说重量单位 有克(g),千克(kg),吨(t) 因此如果使用了该特性,就可以在常量后面跟一个相应的重量单位。

    //所有都返回千克(kg)
    
    long double operator"" _g (long double g)
    {
        return g/1000.0;     
    }
    
    long double operator"" _kg(long double kg)
    {
       return kg;
    }
    
    long double operator"" _t(long double t)
    {
        return t*1000.0;
    }
    
    //接下来我们就可以在代码中很方便的定义使用重量
    long double egg = 50_k;
    long double beauty = 45_kg;
    long double car = 1.5_t;
    //以上代码会很方便的转换成千克单位

    但是,该特性有参数类型和参数个数限制,根据标准,只有以下是合法的:

    1 const char* 
    2 unsigned long long
    3 long double
    4 const char*, size_t 
    5 const wchar_t*, size_t
    6 const char16_t*, size_t 
    7 const char32_t*, size_t

    以上后面的四种版本传入参数直接包含了字符串的长度。

    通过上面可以看到,const char*似乎提供了两个版本(第一行和第四行)一种没有字符串长度,一种有,其实他们是有区别的,不要搞混淆。

    第一行的这种后缀前面的字符串不能加引号,但是必须是数字(十进制或者十六进制的形式),第四行的这种必须加引号。如:

    const char* operator"" _ll(const char* s)
    {
        return s;
    }
    
    const char* operator"" _cc(const char* s, size_t len)
    {
        return s;
    }
    
    //这样使用可以
    123_ll
    0x123a_ll
    "123"_cc
    "0x123a"_cc
    "abc"_cc
    
    //以下使用方式则不行
    abc_ll
    123a_ll //注意与上面的0x123_ll区别
    "123"_ll //不能使用引号
    123_cc
    abc_cc
  • 相关阅读:
    管道及有名管道(pipe与FIFO)
    详细介绍Linux重定向的使用
    Emacs文件和目录操作模式Dired
    exec家族函数
    Seven file types of Unix system(4.3)
    va_list、va_start、va_arg、va_end的原理与使用
    const int*和int const*的区别
    asp.net 文件加载错误
    终于有了属于自己的家,哈哈,很高兴~~
    难得的一场雪
  • 原文地址:https://www.cnblogs.com/uurun/p/4081959.html
Copyright © 2011-2022 走看看