利用宏方便地书写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 ...
随机推荐
- Go项目的测试代码2(项目运用)
上一篇文章介绍了最基本的测试代码的写法.Go项目的测试代码(基础) 这里简单的共享一下我在项目中使用的方式. 项目结构 我们实际项目中, 结构简单地分了控制层controllers和模块层models ...
- 【Makefile】Makefile中的常用函数简介
1. subst函数 格式:$(subst <from>, <to>, <text>)功能:把字串<text>中的<from>字符串替换成& ...
- 在业务控制方法中写入模型变量收集参数,且使用@InitBind来解决字符串转日期类型
1) 在默认情况下,springmvc不能将String类型转成java.util.Date类型,所有我们只能在Action 中自定义类型转换器 <form action="${pa ...
- nodejs获取常见疾病数据示例
日常生活中有一些常见的疾病,这个可以通过百度等搜索到,但是如果你要完成一款app或者小程序.网站之类的该如何来获取常见疾病的信息呢?首先想到的是通过爬虫爬取数据,然后整理搜索....其实这种方法还是太 ...
- File Zilla连接Ubuntu 失败
一.SFTP方式连接失败 站点配置 连接失败 二.FTP连接方式失败 站点配置 连接失败
- [windows] install cross-env with cnpm instead of yarn or npm
环境是 windows下通过vagrant运行虚拟机(ubuntu) Host:windows 10 Guest: ubuntu(vagrant) 根据之前的经验,不要在 Guest环境中执行npm ...
- 手写web框架之实现Bean容器
实现Bean容器 使用ClassHelper可以获取所加载的类,但无法通过类来实例化对象,因此我们需要提供一个反射工具类,让它封装java反射相关的API,对外提供更好用的工具方法.将该类命名为 ...
- 安卓控件支持HTML标签
http://www.cnblogs.com/xqxacm/p/5092557.html
- 视区相关单位vw, vh
vw:相对于视窗的宽度,视窗宽度是100vw vh:相对于视窗的高度,视窗高度是100vh 参考资料:[https://www.zhangxinxu.com/wordpress/2012/09/new ...
- node 笔记整理
node 合并多个请求的数据 function getList1(num) { var url= "netease/search?keyword=独孤天下&type=song& ...