Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concept with multiple template parameters

This

template<typename T, typename U>
concept supports_subscript_op_for_two_indices = requires(T t, U) {
    { t[0] } -> std::same_as<U>;
    { t[1] } -> std::same_as<U>;
};

template<typename T>
concept has_func_returning_int = requires(T t) {
    { t.func() } -> supports_subscript_op_for_two_indices<decltype(t.func()), int>;
};

fails with error "too many template arguments for concept 'supports_subscript_op_for_two_indices'". What could I miss here ? (supposing that I want to use concept to check some structure for func() method, returning something like std::array<int, 2> or anything with [] operator)

like image 849
psb Avatar asked Sep 02 '25 15:09

psb


2 Answers

In a compound requirement, the concept in a type constraint has an implicit first argument. It's the expression one wrote in the compound requirement, parenthesized. It's basically the one you try to supply explicitly, so the compiling syntax would be

{ t.func() } -> supports_subscript_op_for_two_indices<int>;

But that will check supports_subscript_op_for_two_indices<decltype((t.func())), int>. If you were trying to avoid the extra parenthesis being applied (they shouldn't affect the decltype type deduction here, but they may affect it in other cases), you can't use the compound requirement shorthand. You'd need to use an explicit nested requirement:

t.func() ; // Checks the expression is well formed, like we did originally
requires supports_subscript_op_for_two_indices<decltype(t.func()), int>; // check the type constraint on the plain expression
like image 182
StoryTeller - Unslander Monica Avatar answered Sep 05 '25 18:09

StoryTeller - Unslander Monica


From Compound requirements:

  1. If return-type-requirement is present, then:

    a) Template arguments are substituted into the return-type-requirement ;

    b) decltype((expression)) must satisfy the constraint imposed by the type-constraint. Otherwise, the enclosing requires-expression is false.

So, you should change your second concept to

template<typename T>
concept has_func_returning_int = requires(T t) {
    { t.func() } -> supports_subscript_op_for_two_indices<int>;
};

First argument to supports_subscript_op_for_two_indices is automatically decltype(t.func()).

like image 40
pptaszni Avatar answered Sep 05 '25 16:09

pptaszni