码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • C++11之用户自定义字面量(ClassType operator““_C(param...))


    系列文章

    C++11之正则表达式(regex_match、regex_search、regex_replace)

    C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)

    C++11之智能指针(unique_ptr、shared_ptr、weak_ptr、auto_ptr)浅谈内存管理

    C++11之强制类型转换(static_cast,const_cast,dynamic_cast,reinterpret_cast)

    C++11之Lanbda表达式(匿名函数)

    C++11之右值引用:移动语义和完美转发(带你了解移动构造函数、纯右值、将亡值、右值引用、std::move、forward等新概念)

    C++11之继承构造函数(using 声明)

    C++11之委派构造函数

    C++11之显式转换操作符-explicit

    C++11之初始化列表

    C++11之防止类型收窄(列表初始化)


    目录

    • 系列文章
    • 用户自定义字面量
      • 场景案例
      • C++11使用后缀标识符解析字符串
      • C++11使用后缀标识符解析数字
      • 字面量规则
      • 注意


    用户自定义字面量

    在实际的开发过程中,我们会经常使用到结构体来表示一个新的类型。那么在遇到结构体类型都数据进行运算时,只能先依次定义,然后进行运行。这在测试环节会非常的繁琐,为此C++11标准增加了可以通过后缀表示的操作符来将字面量转换为需要的类型。

    场景案例

    例如 我们现在需要使用一个颜色的结构体然后进行合并输出的一个操作,那么实现大概是下面这个样子:

    #include 
    #include 
    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){}
    };
    
    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 << __func__ << endl << col1 << col2 << endl;
    }
    
    int main()
    {
    
    	RGBA col1(255, 255, 255); // C++98 初始化
    	RGBA col2{ 10, 22, 65, 5 }; // C++11 初始化列表
    
    	blend(col1, col2); // 进行运算
    	return 0;
    }
    

    运行结果:

    blend
    r: 255, g: 255, b: 255, a: 0
    r: 10, g: 22, b: 65, a: 5
    

    很明显当我需要进行运算时,必须先依次对变量进行创建,能不能直接传常量到blend函数中呢?C++11就可以做到,后缀标识符配合右值引用完美解决这个问题。

    C++11使用后缀标识符解析字符串

    主要的改动就是需要添加下面这个函数,这个函数的主要功能就是通过解析标识符来定位对应的指针,然后将字符串转换为整型的一个思路。

    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));
    	}
    }
    
    

    然后因为我们需要输入字面常量,所以我们的blend函数的参数就需要将左值引用改成右值引用。

    void blend(RGBA&& col1, RGBA&& col2)
    {
    	cout << __func__ << endl << col1 << col2 << endl;
    }
    
    

    在调用方面也从之前的三行压缩为一行,更加简洁、优雅。

    int main()
    {
    	blend("r255 g240 b155"_C, "r15 g255 b10 a7"_C);
    
    	return 0;
    }
    

    C++11使用后缀标识符解析数字

    对应不同类型的字面量还有着相应的限制,就比如整型类型字面量的参数只能是unsigned long long 或者 const char*。我将在最后对各个类型的要求做一个总结。

    #include 
    #include 
    using namespace std;
    
    
    struct T
    {
    public:
    	int t;
    };
    
    T operator""_t(unsigned long long t)
    {
    	return { static_cast<int>(t) };
    }
    
    int main()
    {
    	T t = 1111_t;
    	return 0;
    }
    
    

    字面量规则

    字面量类型参数要求说明
    整型unsigned long long or const char*当unsigned long long类型无法容纳下该字面量时,编译器会自动将字面量转换为以\0结束的字符串,并调用const char*参数版本的函数来处理
    浮点型long double or const char*和整型的处理相同,long double 容纳不下时,编译器会自动将字面量转换为以\0结束的字符串,并调用const char*参数版本的函数来处理
    字符串(const char*, size_t)只有一种写法
    字符char只有一种写法

    注意

    • 后缀建议以_下划线这种格式。
  • 相关阅读:
    鸿蒙HarmonyOS实战-ArkUI组件(Popup)
    leetcode刷题日记:125. Valid Palindrome(验证回文串)和136. Single Number(只出现一次的数字)
    Android修行手册 - 官方SearchView使用/属性/监听
    传感器|基于改进贪心算法的最佳传感器位置选择(Matlab代码实现)
    2024年腾讯云8核16G18M服务器租用价格1668元15个月
    R 语言入门 —— tidyverse
    MySQL面试题
    微信小程序中生成普通二维码,并根据二维码里的参数跳转对应的页面
    spark
    openjudge 1.12.8 Vigenere密码
  • 原文地址:https://blog.csdn.net/qq_45254369/article/details/127095044
  • 最新文章
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
    用 Hashids 优雅解决 C 端自增 ID 暴露问题
    V8引擎 精品漫游指南--Ignition篇(上) 指令 栈帧 槽位 调用约定 内存布局 基础内容
    LLVM Pass快速入门(四):代码插桩
    milkup:桌面端 markdown AI续写和即时渲染
    基于项目工程构建SBOM(软件物料清单)的研究
    鸿蒙应用开发UI基础第二节:鸿蒙应用程序框架核心解析与实操
    .NET 中如何快速实现 List 集合去重?
    扣子Coze实战:从0到1打造抖音+小红书热点监控智能体
    浅谈数据访问层
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号