2

我想升级我的自定义容器以与std::ranges诸如find_if和其他算法兼容,如下所示

auto is_satisfy = [](CustomContainer::value_type x) { ... };
std::ranges::find_if(custom_container, is_satisfy);
// instead of std::find_if(custom_container.begin(), custom_container.end(), is_satisfy);

std::ranges::find_if喜欢的签名

struct find_if_fn {
   template< ranges::input_range R,
            class Proj = std::identity,
            std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>,
                                         Proj>> Pred >
   constexpr ranges::borrowed_iterator_t<R>
   operator()( R&& r, Pred pred = {}, Proj proj = {} ) const
   {
       return (*this)(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj));
   }
};

什么是input_range 概念以及我自己的自定义容器如何支持此功能?

4

1 回答 1

3

什么是 input_range 概念

它是这个:

template<class T>
  concept input_­range =
    range<T> && input_­iterator<iterator_t<T>>;

在英语中,input_range 是一个迭代器为 input_iterator 的范围。另一方面,范围概念是:

范围概念通过提供表示范围元素的迭代器和哨兵来定义允许对其元素进行迭代的类型的要求。

template<class T>
  concept range =
    requires(T& t) {
      ranges::begin(t); // sometimes equality-preserving
      ranges::end(t);
    };

input_iterator 是:

input_iterator 概念定义了一个类型的要求,该类型的引用值可以被读取(从indirectly_readable ([iterator.concept.readable]) 的要求中)并且可以是前后递增的。[注 1:与 Cpp17InputIterator 要求 ([input.iterators]) 不同,input_iterator 概念不需要相等比较,因为迭代器通常与哨兵进行比较。——尾注]

template<class I>
  concept input_­iterator =
    input_­or_­output_­iterator<I> &&
    indirectly_­readable<I> &&
    requires { typename ITER_CONCEPT(I); } &&
    derived_­from<ITER_CONCEPT(I), input_iterator_tag>;

您可以阅读相关概念、功能和特征的规范以获取详细信息。

我自己的自定义容器如何支持此功能?

简而言之:通过符合上述概念。

中:提供成员函数beginend其中前者应返回输入迭代器,后者应返回兼容的哨兵类型(可能与迭代器类型相同或不同)。结束标记应该从一开始就可以到达,并且表示超过范围的最后一个元素。

一般来说,我建议查看标准容器的 API,以了解它们提供了哪些成员以及它们是如何工作的。将设计复制到您的自定义容器中。


报价来自最新的标准草案。

于 2021-02-12T11:22:41.953 回答