Is there some way to specify if template param of function is specific template class?

I will explain my question based on following example:

template <typename Param1, typename Param2>
class foo1
{
  void lol();
};

template <typename Param1, typename Param2>
class foo2
{
  void lol();
};

////////////////////////// FIRST OPTION //////////////////////////

template <typename Param1, typename Param2>
void func(foo1<Param1, Param2> a)
{
  a.lol();
  a.lol();
}

template <typename Param1, typename Param2>
void func(foo2<Param1, Param2> a)
{
  a.lol();
}

////////////////////////// SECOND OPTION //////////////////////////

template <typename Foo_>
void func(Foo_ a)
{
  a.lol();
  a.lol();
}

///////////////////////////////////////////////////////////////////

int main()
{
  return 0;
}

My goal is to write two overloads of func – for foo1 and foo2.
The FIRST OPTION works fine, but I don’t like that I have to write template parameters for func that are not used in it.
Is there some way to avoid writing template parameters in signature of func?

I thought of writing something like this SECOND OPTION, but the problem is that overloads do different things.

>Solution :

The template parameters are used. Without them, foo1 and foo2 are just class templates and not a classes.

A simple way to minimize the typing would be to use template parameter packs:

template<class... T>
void func(foo1<T...> a) {
    a.lol();
    a.lol();
}

template<class... T>
void func(foo2<T...> a) {
    a.lol();
}

If you need this check a lot, you can create concepts (since C++20):

#include <type_traits>

// concept for foo1:
template <class T> struct is_foo1 : std::false_type {};
template <class P1, class P2> struct is_foo1<foo1<P1, P2>> : std::true_type {};
template <typename T> concept Foo1Type = is_foo1<T>::value;

// concept for foo2:
template <class T> struct is_foo2 : std::false_type {};
template <class P1, class P2> struct is_foo2<foo2<P1, P2>> : std::true_type {};
template <typename T> concept Foo2Type = is_foo2<T>::value;

Then the func overloads become simpler:

void func(Foo1Type auto a) {    
    a.lol();
    a.lol();
}

void func(Foo2Type auto a) {    
    a.lol();
}

Demo

Leave a Reply