利用宏方便地书写raw string literals
以前一直没用过标准库的regex,今天写一个hlsl的解析工具的时候用了一下,发现用字符串字面值写regular expression的时候非常不方便,特别是每个“\”字符都要被识别为转义,只能写成“\\”。比如,一系列空白字符加一个数字要写成这样:
std::regex reg("\\s*\\d");
这样一来,稍微一复杂的regular expression就完全没法看了。理所当然地,可以用raw string literal来解决这个问题。C++11中raw string literal的写法是这样的:
R"delimiter(string)delimiter"
其中delimiter是用来标识字符串的边界的。比方说——
std::cout << R"__("minecraft")__"
输出的结果就是"minecraft",注意输出的结果是有引号的。
用raw string literal的时候我就觉得,能不能把它搞得更直观一点,比如上面那个regular expression能不能写成
#define RAW_STR(str) something... std::regex reg(RAW_STR(\s*\d));
于是我试着写了一个
#define RAW_STR(str, delimiter) R##"##delimiter##(##str##)##delimiter##"
结果发现##delimiter##(##str##)##delimiter##直接被两边的引号界定为了字符串字面值,str和delimiter作为宏参数根本没被展开出来。于是加了一层宏——
#define __ADD_QUOT(s) #s
专门用来添加引号。这时候又想起在有##或#的时候宏参数不会被展开,所以加了个中间层来展开参数:
#define __ADD_QUOT(s) __ADD_QUOT_AUX(s) #define __ADD_QUOT_AUX(s) #s
就这样来来回回加了几个中间层,最后就变成了这样:
#define RAW_STR(str) \
__RAW_STR_AUX_ADD_R(__RAW_STR_AUX_MAKE_STR(__RAW_STR_AUX_CAT(str)))
#define __RAW_STR_AUX_ADD_R(str) __RAW_STR_AUX_ADD_R1(str)
#define __RAW_STR_AUX_ADD_R1(str) R##str
#define __RAW_STR_AUX_MAKE_STR(cont) __RAW_STR_AUX_MAKE_STR1(cont)
#define __RAW_STR_AUX_MAKE_STR1(cont) #cont
#define __RAW_STR_AUX_CAT(str) __RAW_STR_AUX_CAT1(str)
#define __RAW_STR_AUX_CAT1(str) _____##(##str##)##_____
这里我用四个下划线作为delimiter,一般来说够用了。然后试了一下,还算能用。但是有个毛病没有解决:字面值的两端如果有“,”字符,会被预处理器当做宏参数的分隔符,而非宏参本身的一部分,导致不正确的结果。在写regular expression的时候,把这样的特殊字符用圆括号包起来就行了(反正对语义没有影响),比如
std::regex reg(RAW_STR(minecraft(,)));
当然,这个问题也许有更好的解决方法,以后再慢慢考虑。严格来说,这一堆宏在理论和工程上都没有什么用,就当自己寒假玩一玩了。
利用宏方便地书写raw string literals的更多相关文章
- C++11中的raw string literals
作为一名C++书看得少得可怜的新手,我一直没有勇气去系统地学习一下C++ 11添加的新特性.不过,平日里逛论坛,阅读大犇们的博客,倒是了解了一些.比如,这个帖子: 如何绕过g++ 4.8.1那个不能在 ...
- 指针直接赋值为整型AND利用宏定义求结构体成员偏移量
首先我们要更正一个很熟悉的概念,那就是指针不仅仅是“地址”,指针还有一个很重要的特性,那就是“类型”. 指针初始化时,“=”的右操作数; 除外,该语句表示指针为空): 所以 ; 这样的代码是不允许的. ...
- python raw String 获取字符串变量中的反斜杠
常用的获取raw string的方式为: >>>r'\n' \n 不能用在字符串变量中,获取字符串变量中的反斜杠如下: tab = '\n' >>>tab.enco ...
- react 使用 ref 报错 ,[eslint] Using string literals in ref attributes is deprecated. (react/no-string-refs)
react 项目中给指定元素加事件,使用到 react 的 ref 属性,Eslink 报错 [eslint] Using string literals in ref attributes is d ...
- Visual Studio 2010如何利用宏
最近在做后台代码的拆分,由于机器升级,原来装的添加注释的插件不能用了. 看来只有自己想办法了,看了下利用宏添加注释与把项目展开.折叠的方式: 参考了以下几个内容: 1.Visual Studio 20 ...
- (转)react 使用 ref 报错 ,[eslint] Using string literals in ref attributes is deprecated. (react/no-string-refs)
原文地址:https://www.cnblogs.com/gangerdai/p/7396226.html react 项目中给指定元素加事件,使用到 react 的 ref 属性,Eslink 报错 ...
- python中的raw string的使用
背景 我们经常需要使用raw string,在应用过程中,比如要使字符串中带一些转义字符或者其他的一些符号,我们就需要保持我们的字符成为raw string. 实例 输入 s = 'fadfafa\n ...
- C++ raw string literal
raw string literal 以 R"( 开头, )" 结束,是可以跨越多行的字符串字面值,转义字符如 \t\n 在raw string literal中是普通的文本 ...
- word中利用宏替换标点标点全角与半角
Alt+F11,然后插入-模块: 复制下面代码到编辑窗口: Sub 半角标点符号转换为全角标点符号() '中英互译文档中将中文段落中的英文标点符号替换为中文标点符号 Dim i As Paragrap ...
随机推荐
- 括号序列模型--序列dp--U86873 小Y的精灵国机房之旅
括号序列模型及解法 >Codeforces314E◦给定一个长度为n的仅包含左右括号和问号的字符串,将问号变成左括号或右括号使得该括号序列合法,求方案总数.◦例如(())与()()都是合法的括号 ...
- 1.springboot内置tomcat的connection相关
最近在研究tomcat的连接超时问题,环境:jdk1.8 + springboot 2.1.1.RELEASE,以下仅为个人理解,如果异议,欢迎指正. springboot的tomcat的几个配置参数 ...
- 客户端连接虚拟机上的MYSQL报错
这个原因是因为虚拟机的数据库拒绝其他主机访问 所以需要设置虚拟机的mysql 打开mysql mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' ID ...
- 相似系数_杰卡德距离(Jaccard Distance)
python机器学习-乳腺癌细胞挖掘(博主亲自录制视频)https://study.163.com/course/introduction.htm?courseId=1005269003&ut ...
- linux的dos开关机命令
常用:halt.reboot CentOS关机命令: 重启命令 reboot shutdown -r now 立刻重启 shutdown -r 10 过10分钟自动重启 shutdown -r 20: ...
- 阿里云安装 fastdfs 总结
还要开放 23000 22122,添加进安全组
- 一百二十六:CMS系统之轮播图管理页面布局和添加轮播图的模态对话框制作
视图 @bp.route('/banners/')@login_required@permission_required(CMSPersmission.POSTER)def banners(): re ...
- 使用throw和throws 引发异常
1.throw 用在方法内抛出异常,通常可以自行使用try catch进行异常处理 如果不自行处理的话,需要在方法上使用throws抛出异常 public static void testAge(){ ...
- Centos7 搭建Svn+Apache服务器
Svn客户端搭建 1.yum install subversion 2.查看安装版本 svnserve --version 3.创建SVN版本库目录 mkdir -p /opt/svn 4.创建版本库 ...
- JAVA_day1_变量和常量
JAVA变量和常量 一.JAVA中的关键字 注:关键字区分大小写,Try不是关键字而try则是. 二.JAVA标识符 1.标识符:标识符就是用于给 Java 程序中变量.类.方法等命名的符号. 2.标 ...