So I need to find out if two templates are the same, even if the parameters are not, ie. if in T<A> and U<B> T and U are the same, even if A and B are not. std::is_same can't be used, as it only regards the full type.
My first solution was this:
template<typename T, typename U>
struct is_same_template : std::false_type {};
template<template<typename> typename T, typename A, typename B>
struct is_same_template<T<A>, T<B>> : std::true_type {};
template<template<typename> typename T, typename A, template<typename> typename U, typename B>
struct is_same_template<T<A>, U<B>> : std::false_type {};
It works, but only for templates with one parameter, so I extended it to:
template<typename T, typename U>
struct is_same_template : std::false_type {};
template<template<typename...> typename T, typename... A, typename... B>
struct is_same_template<T<A...>, T<B...>> : std::true_type {};
template<template<typename...> typename T, typename... A, template<typename...> typename U, typename... B>
struct is_same_template<T<A...>, U<B...>> : std::false_type {};
That works great, even for templates with parameter packs.
Example:
template <typename... Params>
struct Test1 {};
template <typename... Params>
struct Test2 {};
struct Foo {};
struct Bar {};
int main(int argc, char** argv) {
std::cout << std::boolalpha;
std::cout << is_same_template<Test1<Foo>, Test2<Foo>>::value << '\n';
std::cout << is_same_template<Test1<Foo>, Test2<Bar>>::value << '\n';
std::cout << is_same_template<Test1<Foo, Bar>, Test2<Bar>>::value << '\n';
std::cout << is_same_template<Test1<Foo>, Test1<Foo>>::value << '\n';
std::cout << is_same_template<Test1<Foo>, Test1<Bar>>::value << '\n';
std::cout << is_same_template<Test1<Foo, Bar>, Test1<Bar>>::value << '\n';
return 0;
}
Output:
false
false
false
true
true
true
My problem is that in the actual use case I did this for the template parameter is an int parameter pack:
template <int... Indexes>
struct ArgIndexes {};
I didn't know that types and non-types are handled differently. When testing with ArgIndexes the result was always the value of
template<typename T, typename U>
struct is_same_template : std::false_type {};
Is there any way to get this to work with both type and non-type parameter packs without handling every kind of non-type parameter pack specifically?
EDIT
I just realized that
template<template<typename...> typename T, typename... A, template<typename...> typename U, typename... B>
struct is_same_template<T<A...>, U<B...>> : std::false_type {};
is redundant and can be removed.