关于ranges-v3库中`template(bool Other)( requires ....) classname(...)`语法的技术咨询
template(bool Other)( requires ....) classname(...)语法的技术咨询 嘿,我看到你在研究ranges-v3里concat_view的实现时,碰到了这段看起来有点陌生的sentinel结构体代码,还对里面的模板构造函数语法产生了疑问,刚好我对这块内容比较熟悉,来给你详细拆解下。
先把你贴的截断代码补全下,方便对照:
template
struct sentinel {
private:
friend struct sentinel<!IsConst>;
friend struct cursor;
template
using constify_if = meta::const_if_c<IsConst, T>;
using concat_view_t = constify_if<concat_view>;
// 就是这个让你困惑的构造函数
template(bool Other)
requires (IsConst || !Other)
sentinel(sentinelthat)
: it_(std::move(that.it_))
{}
};
首先得明确:这个template(bool Other)(requires ...)的写法不是标准C++的原生语法,是ranges-v3开发团队为了简化模板代码可读性搞的语法糖,本质上等价于标准C++里的template<bool Other> requires (...)结构。
那这个构造函数的作用是什么呢?它是用来实现不同const限定版本的sentinel之间的安全转换:
- 允许从非const的
sentinel<false>转换到const的sentinel<true>(这就像普通指针可以转const指针一样,是合理的只读转换) - 但禁止从const的
sentinel<true>转换到非const的sentinel<false>(防止意外修改被const修饰的对象)
而那个requires (IsConst || !Other)的约束就是来保证这个规则的:只有当当前sentinel是const版本(IsConst为true),或者传入的sentinel是非const版本(Other为false)时,这个构造函数才会被编译器认可。
另外结构体里的constify_if辅助类型,是用meta::const_if_c根据IsConst的布尔值,给目标类型自动加上const限定——比如constify_if<concat_view>,当IsConst为true时就是const concat_view,否则就是普通的concat_view,这也是为了配合不同const版本的迭代器、哨兵的使用场景,让代码能自动适配const和非const的视图对象。
这种语法糖的好处很明显:把模板参数的声明从template<bool Other>简化成template(bool Other),少了尖括号的嵌套,在处理大量元编程代码时,能让结构更清爽,可读性提升不少。不过要记住,这是ranges-v3特有的写法,你在标准C库或者其他普通C项目里是碰不到的哦。
内容来源于stack exchange

