Let's say I have two structs, Foo
and Bar
:
template<int...>
struct Foo{};
template<unsigned long...>
struct Bar{};
I want to create a type trait (call it match_class
) that returns true if I pass two Foo<...>
types or two Bar<...>
types, but false if I try to mix them:
int main()
{
using f1 = Foo<1, 2, 3>;
using f2 = Foo<1>;
using b1 = Bar<1, 2, 3>;
using b2 = Bar<1>;
static_assert(match_class<f1, f2>::value, "Fail");
static_assert(match_class<b1, b2>::value, "Fail");
static_assert(!match_class<f1, b1>::value, "Fail");
}
For C++1z (clang 5.0.0 and gcc 8.0.0) it's sufficient to do this (Demo):
template<class A, class B>
struct match_class : std::false_type{};
template<class T, template<T...> class S, T... U, T... V>
struct match_class<S<U...>, S<V...>> : std::true_type{};
But in C++14 I get the following error (same compilers* Demo):
error: class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used [-Wunusable-partial-specialization]
struct match_class<S<U...>, S<V...>> : std::true_type{};
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: non-deducible template parameter 'T'
template<class T, template<T...> class S, T... U, T... V>
Question: What is a workaround for this in C++14?
Ideally the syntax for testing the type trait should remain the same.
Secondary question: Is the behavior for C++14 correct? (or alternatively is the behavior I see for C++17 unspecified?)
*Note that MSVC 19.00.23506 has the same kind of failure Demo
template<template<auto ...> class S, auto... U, auto... V> struct match_class<S<U...>, S<V...>> : std::true_type{};
. – Schistauto
template arguments is not C++14 compatible, I left it out :-) – Winshell