Search code examples
c++metaprogrammingc++-concepts

Combining Variadic Template Concept


I am trying to apply a concept defined on a single template class on multiple template classes and I do:

template<template<class> class F, class T, class... Ts>
    requires F<T>::value
struct check_concept
{
    constexpr bool value = check_concept<F, Ts...>::value;
};

template<template<class> class F, class T>
    requires F<T>::value
struct check_concept<F, T>
{
    constexpr bool value = true;
};

I get an error saying: 'check_concept<F,T,>::value' cannot be declared with 'constexpr' specifier.

I would like to do something like:

template<class... Ts>
    requires check_concept<std::is_arithmetic, Ts...>::value;
class A
{
    //Implementation Details
}

I tried inheriting each time from check_concept<template<class> class F, class... Ts> but still fails.


Solution

  • First: you have "typo", missing static: i.e static constexpr bool value =.

    Second: with your attempt, check_concept<F, Ts...>::value is always true or rejected. You should instead do:

    template<template<class> class F, class T, class... Ts>
    struct check_concept
    {
        static constexpr bool value = F<T>::value && check_concept<F, Ts...>::value;
    };
    
    template<template<class> class F, class T>
    struct check_concept<F, T>
    {
        static constexpr bool value = F<T>::value;
    };
    

    Demo

    Third: no need of recursion for the definition, fold expression is enough:

    template <template <class> class F, class... Ts>
    struct check_concept
    {
        static constexpr bool value = (F<Ts>::value && ...);
    };
    

    Demo

    Finally, from the simple definition, that helper is not really needed, and A might directly be:

    template<class... Ts>
        requires ((std::is_arithmetic<Ts>::value && ...));
    // or requires std::disjunction_v<std::is_arithmetic<Ts>...>;
    class A
    {
        // Implementation Details
    };