Search code examples
c++c++-concepts

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)


Solution

  • 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