Скажем, у меня две структуры: Foo
и Bar
:
template<int...>
struct Foo{};
template<unsigned long...>
struct Bar{};
Я хочу создать признак типа (назовите его match_class
), который возвращает true, если я передаю два типа Foo<...>
или два типа Bar<...>
, но false, если я попытаюсь их смешать:
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");
}
Для С++ 1z (clang 5.0.0 и gcc 8.0.0) достаточно сделать это (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{};
Но в С++ 14 я получаю следующую ошибку (такие же компиляторы *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>
Вопрос: что такое обходной путь для этого в С++ 14?
В идеале синтаксис для проверки черты типа должен оставаться тем же.
Вторичный вопрос: Правильно ли поведение для С++ 14? (или, альтернативно, поведение, которое я вижу для С++ 17, не указано?)
* Обратите внимание, что MSVC 19.00.23506 имеет такой же отказ Демо