特定类型的范围概念

Ami*_*rsh 11 c++ c++-concepts c++20 std-ranges

在 C++20 或 range-TS 中是否有一个已经定义的概念来指定特定类型的范围?

就像是:

template < class T, class InnerType >
concept RangeOf =
  requires(T&& t) {
    requires std::same_as<
           std::remove_cvref_t<decltype(*std::ranges::begin(t))>,
           InnerType
         >;
    std::ranges::end(t);
  };
Run Code Online (Sandbox Code Playgroud)

允许,例如

void print(const RangeOf<char> auto& char_seq) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 19

不,没有。

拼写该特定概念的方法是:

template <typename R, typename V>
concept RangeOf = range<R> && same_as<range_value_t<R>, V>;
Run Code Online (Sandbox Code Playgroud)

但事实证明,您可能还想检查一堆非常密切相关的事情。您可能实际上想查看类型reference而不是value_type. 也许那就是:

template <typename R, typename V>
concept RangeOf = range<R> && same_as<range_reference_t<R>, V>;
Run Code Online (Sandbox Code Playgroud)

原因是:你认为vector<char>&是一个范围char还是一个范围char&?可以说,它更像是后者,而正是后者推动了更多的使用。但这并不是说前者是错误的;而是前者是错误的。它也很有用,只是方式不同。

然后你必须谈论你是否想要same_asconvertible_to。在某些算法中,您希望限制为前者,而在某些算法中,后者就足够好了。

same_as对我来说, vs的这个问题convertible_to是需要概念模板参数的动机之一,因此:

template <typename R, template <typename> concept C>
concept RangeOf = range<R> && C<range_value_t<R>>;
Run Code Online (Sandbox Code Playgroud)

这样我就可以轻松地编写RangeOf<same_as<char>>RangeOf<convertible_to<char>>,这取决于我真正想要的。然而,这也带来了其他解析问题(如果RangeOf采用一元概念,你如何使same_as<char>- 这不是一个一元概念,而是一个在所有上下文中都无效的部分应用概念 - 工作?)所以目前还不清楚如何真正工作使这项工作发挥作用。目前有一个建议,但它实际上并不能特别好地处理这个用例(主要是因为实际上并不清楚如何特别好地处理这个用例)。


所有这些都是说,很难知道我们真正想要什么RangeOf,这就是为什么不存在这样的东西。但是每个有用的具体东西都很容易编写,因此缺少这样的东西对用户来说并不是特别大的负担。