[C++11阅读][2-4-1]用户自定义字面量

2020-06-12  本文已影响0人  凌霄阁2010

字面量

C/C++一直有字面量这个概念,比如32L是个long、19.0f是float、0x32是16进制整数。

用户自定义字面量

在C++11中,用户可以自定义字面量了,语法上是重载引号运算符实现的,引号后面接个空格,接个下划线,再接用户自定义的符号。
看一个例子,用_C表示一个RGBA的字面量,实例化两个匿名对象出来。

#include <cstdlib>
#include <iostream>
using namespace std;
typedef unsigned char uint8;
struct RGBA {
        uint8 r;
        uint8 g;
        uint8 b;
        uint8 a;
        RGBA(uint8 R, uint8 G, uint8 B, uint8 A = 0):
                r(R), g(G), b(B), a(A){}
};
RGBA operator "" _C(const char* col, size_t n) {
        const char* p = col;
        const char* end = col + n;
        const char *r, *g, *b, *a;
        r = g = b = a = nullptr;
        for (; p!=end; ++p) {
                if (*p == 'r') r = p;
                else if (*p == 'g') g = p;
                else if (*p == 'b') b = p;
                else if (*p == 'a') a = p;
        }
        if (r == nullptr || g == nullptr || b == nullptr)
                throw;
        else if (a == nullptr)
                return RGBA(atoi(r+1), atoi(g+1), atoi(b+1));
        else
                return RGBA(atoi(r+1), atoi(g+1), atoi(b+1), atoi(a+1));
}
std::ostream & operator << (std::ostream & out, RGBA & col) {
        return out << "r: " << (int)col.r
                << ", g: " << (int)col.g
                << ", b: " << (int)col.b
                << ", a: " << (int)col.a << endl;
}
void blend(RGBA && col1, RGBA && col2) {
        cout << "blend " << endl << col1 << col2 << endl;
}
int main() {
        blend("r255 g240 b155"_C, "r15 g255 b10 a7"_C);
}
// -std=c++11
/*
blend 
r: 255, g: 240, b: 155, a: 0
r: 15, g: 255, b: 10, a: 7
*/

不同类型的规则

虽然重载的符号是引号,但可以支持四种类型,支持的类型是整数、浮点数、字符串、字符。

  1. 如果字面量是整型数,那么字面量操作符函数只可接受unsigned long long或者const char为其参数。当数太大,unsigned long long无法容纳该字面量的时候,编译器会自动将该字面量转化成以\0为结束符的字符串,用调用以const char为参数的函数版本。
  2. 如果字面量为浮点型,则字面量操作符函数只可接受long double或者const char为其参数。const char规则跟整形一样,太长的用这个函数。
  3. 如果字面量为字符串,则字面量操作符只可接受(const char*, size_t)为参数,已知长度的字符串。
  4. 如果字面量为字符,则字面量操作符只可接受一个char为参数。

函数声明格式

声明字面量操作符函数时,有以下几点需要注意。

  1. operator ""与用户自定义后缀之间必须有空格。
  2. 后缀建议以下划线开始,不带下划线时会被编译器警告。
    g++实测并没有被警告。
上一篇 下一篇

猜你喜欢

热点阅读