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.
CodePudding user response:
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 concept
s (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();
}