Search code examples
c++templatesconstraintsvariadic-templatesc++-concepts

Single template parameter concept type constraint for multiple parameter template type


I have a custom templated class type:

template<T1, T2, T3>
class MyType{
   public:
     using value_type = T1;
     value_type val();
   private:
     T1 val;
}

I would like to make a simple concept type:

template<>
concept = MyTypeTemplateType

in order to write

template<MyTypeTemplateType>
MyType myFunc(T arg){
    //some stuff. e.g.
    return MyType{std::abs(arg.val())};
};

}

What I have so far is:

template<typename... Ts>
concept MyTypeTemplateType= requires(MyType<Ts...> arg) {
                       arg.val();
                   };

However, when I do:

MyType<int, float, float> myVal{5};
auto myVal2 myFunc(myVal);

I get a compiler error:

In substitution of 'template requires MyTypeTemplateType T myFunc(T) [with T = MyType<int, float, float>]';
required for the satisfaction of 'MyTypeTemplateType' [with T = MyType<int, float, float>]
in requirements with 'MyType<Ts ...> arg' [with Ts = {int, float, float}]
wrong number of template arguments (1, should be 3)

I would need to decompose T into a template pack Ts it seems...

Any ideas? I'm fairly new to concepts and template parameters packs.


Solution

  • As I understand, you might create a traits:

    template <typename T>
    struct IsMyType : std::false_type {};
    
    template <typename T1, typename T2, typename T3>
    struct IsMyType<MyType<T1, T2, T3>> : std::true_type {};
    

    and then

    template <typename T>
    concept MyTypeTemplateType = IsMyType<T>::value;