c++ - 在自定义容器上使用范围算法

标签 c++ c++20 c++-concepts std-ranges

我想升级我的自定义容器以兼容 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 concept我自己的自定义容器如何支持此功能?

最佳答案

What is the input_range concept

是这样的:

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

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

The range concept defines the requirements of a type that allows iteration over its elements by providing an iterator and sentinel that denote the elements of the range.

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

而 input_iterator 是:

The input_­iterator concept defines requirements for a type whose referenced values can be read (from the requirement for indirectly_­readable ([iterator.concept.readable])) and which can be both pre- and post-incremented. [Note 1: Unlike the Cpp17InputIterator requirements ([input.iterators]), the input_­iterator concept does not need equality comparison since iterators are typically compared to sentinels. — end note]

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>;

您可以阅读依赖项概念、功能和特征的规范以了解确切的详细信息。

how this feature is supported by my own custom container?

简而言之:通过符合上面显示的概念。

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

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


引用来自最新的标准草案。

关于c++ - 在自定义容器上使用范围算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66170617/

相关文章:

c++ - 如何实现与参数顺序无关的 std::same_as 的广义形式(即对于两个以上的类型参数)?

c++ - 在 main 启动之前访问命令行

C++,函数将数组作为字符串返回

c++ - 应该弃用 std::list 吗?

c++ - 使用模板参数列表调用 lambda,不提供参数

c++ - [[不太可能]]可以用循环吗?

c++ - 概念示例的简单 C++ 接口(interface)

c++ - 我怎样才能为一个概念重载一个函数?

c++ - stringstream 重复最后一个词

c++ - 将字符串存储在 constexpr 结构中