首页 > 解决方案 > 满足 std::ranges::range 概念

问题描述

在即将到来的 C++20 范围中,将出现具有以下定义的范围概念:

template< class T >
concept range = __RangeImpl<T&>; // exposition-only definition

template< class T >
concept __RangeImpl = requires(T&& t) {
  ranges::begin(std::forward<T>(t)); // equality-preserving for forward iterators
  ranges::end  (std::forward<T>(t));
};

template< class T >
concept __ForwardingRange = ranges::range<T> && __RangeImpl<T>;

将其翻译成简单的英语我想说,满足范围概念的类型的唯一要求是可以使用 range::begin 和 range::end 调用。

但是,如果我创建一个空类型,只是开始和结束范围概念上的静态断言会失败吗?

namespace ranges = std::experimental::ranges;

struct A {
  void begin() {}
  void end() {}
};

static_assert(ranges::range<A>);

我错过了什么?

标签: c++rangec++-concepts

解决方案


[range.access.begin]:(强调我的)

该名称ranges​::​begin表示自定义点对象ranges​::​​begin(E)某些子表达式的E表达式等价于:

  • [...]

  • 否则,如果E是一个左值,decay-copy(E.begin())如果它是一个有效的表达式和它的类型I模型 input_­or_­output_­iterator

  • [...]

你的A,A.begin()是 type void,它不可能是一个迭代器。因此,ranges::begin(std::declval<A>())无效。


推荐阅读