C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Allow using type alias in requires-clause

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Wed, 16 Aug 2023 11:59:54 -0400
On Wed, Aug 16, 2023 at 11:56 AM Arthur O'Dwyer via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> On Wed, Aug 16, 2023 at 11:39 AM Kang Hewill via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> Hello all C++ experts,
>>
>> I find it very convenient to allow using-type alias in the requires-clause.
>>
>> For complex type aliases, simplifying them with using-alias can reduce redundant spelling for subsequent constraint checks on the same type alias.
>>
>> Take the standard concept indirectly-readable-impl as an example:
>>
>> template<class In>
>> concept indirectly-readable-impl =
>> requires(const In in) {
>> typename iter_value_t<In>;
>> typename iter_reference_t<In>;
>> typename iter_rvalue_reference_t<In>;
>> { *in } -> same_as<iter_reference_t<In>>;
>> { ranges::iter_move(in) } -> same_as<iter_rvalue_reference_t<In>>;
>> } &&
>> common_reference_with<iter_reference_t<In>&&, iter_value_t<In>&> &&
>> common_reference_with<iter_reference_t<In>&&, iter_rvalue_reference_t<In>&&> &&
>> common_reference_with<iter_rvalue_reference_t<In>&&, const iter_value_t<In>&>;
>>
>> we can simplify it to:
>>
>> template<class In>
>> concept indirectly-readable-impl =
>> requires(const In in) {
>> using value_type = typename iter_value_t<In>;
>> using reference = typename iter_reference_t<In>;
>> using rvalue_reference = typename iter_rvalue_reference_t<In>;
>> { *in } -> same_as<reference>;
>> { ranges::iter_move(in) } -> same_as<rvalue_reference>;
>> requires common_reference_with<reference&&, value_type&>;
>> requires common_reference_with<reference&&, rvalue_reference&>;
>> requires common_reference_with<rvalue_reference&&, const value_type&>;
>> };
>>
>> Do you think it's worth supporting this using-alias syntax in the requires-clause?
>
> That seems reasonable to me, except that you need a story about alias templates. Are you also proposing to support e.g.
> template<class A>
> concept Allocator = requires (const A& a) {
> template<class T> using rebound = std::allocator_traits<A>::rebind<T>;
> rebound<int>(a);
> requires std::same_as<rebound<int>::value_type, int>;
> };
> Does that close any doors to syntax we might want in the future?
>
> If you can't support alias templates just as well as aliases, then you're going to need much stronger motivation. I have the gut feeling that permitting alias declarations in concepts might indeed simplify some code... but the example you've actually presented here doesn't "simplify." It makes the code exactly the same length, and IMHO less readable (because now we have multiple ways of spelling the same types, making it harder to follow what's going on and what's dependent on what).
>
> Plus, the major change you made there doesn't have anything to do with aliases — you merely moved the previously-subsumed sub-concepts into the requires-expression. That could be done today, if we didn't care about subsumption; and it can't be done tomorrow, if we continue to care about subsumption. So your example is not only not-very-motivating, it's also apples-to-oranges.

It's unclear how this breaks subsumption. Are type aliases meaningful
to subsumption?

Received on 2023-08-16 16:00:07