如何理解C++ Concepts中std::weakly_incrementable的文档要求?
我正在学习C++的Concepts特性,想要创建一个符合std::weakly_incrementable概念的类型。该概念的定义如下:
template< class I > concept weakly_incrementable = std::movable<I> && requires(I i) { typename std::iter_difference_t<I>; requires /*is-signed-integer-like*/<std::iter_difference_t<I>>; { ++i } -> std::same_as<I&>; // 不要求保持相等性 i++; // 不要求保持相等性 };
我理解该类型需要满足:
- 拥有返回I类型引用的前置递增运算符
- 拥有后置递增运算符
因此最初写出如下结构:
struct I { void operator*() {} I& operator++() { return *this; } void operator++(int){} };
但我不清楚其中类型要求typename std::iter_difference_t<I>;和requires /*is-signed-integer-like*/<std::iter_difference_t<I>>;具体指什么。后来通过示例发现需要定义difference_type,修改后的结构如下:
struct I { using difference_type = int; // 满足类型要求所需 void operator*() {} I& operator++() { return *this; } void operator++(int){} };
我想知道如何从文档中得知需要定义名为difference_type的类型,而非iter_difference_t或其他类型?
解答
关键在于std::iter_difference_t<I>的推导规则——它并不是要求你直接定义这个类型,而是会根据I的结构自动推导对应的差值类型,推导优先级为:
- 若
I是指针类型,iter_difference_t<I>直接等价于std::ptrdiff_t; - 否则,检查
I是否包含嵌套的difference_type成员类型,若有,iter_difference_t<I>就等于该类型; - 若以上都不满足,会尝试从
std::iterator_traits<I>::difference_type获取,但对于自定义类型,默认的iterator_traits同样依赖你在I中定义difference_type。
回到std::weakly_incrementable的要求,typename std::iter_difference_t<I>本质是验证:针对类型I,iter_difference_t能够推导出一个合法类型。而要让推导合法,对于自定义的可递增类型,最直接的方式就是在类型中定义嵌套的difference_type——这是C++标准迭代器体系的约定规则,所有标准迭代器概念都遵循这个嵌套类型的命名规范。
标准文档中对std::iter_difference_t的定义明确说明了推导逻辑优先使用类型自身的difference_type成员,这就是为什么需要定义这个嵌套类型,而非iter_difference_t(后者是一个工具别名,不是需要你定义的类型)。
内容的提问来源于stack exchange,提问作者roi_saumon

