Предложение: попробуйте что-нибудь следующим образом
struct inner {
using TA = std::tuple<As...>;
using TB = std::tuple<Bs...>;
template<bool dummy, typename UA = TA, typename E = void>
struct problem;
template<bool dummy, typename UA>
struct problem<dummy, UA,
std::enable_if_t<(std::tuple_size_v<UA> < std::tuple_size_v<TB>)>>
{ static constexpr auto val() { return 1; } };
template<bool dummy, typename UA>
struct problem<dummy, UA,
std::enable_if_t<(std::tuple_size_v<UA> >= std::tuple_size_v<TB>)>>
{ static constexpr auto val() { return 0; } };
};
Я имею в виду ... принять во внимание, что SFINAE работает с тестами над параметром шаблона структуры / класса (или функции, или метода), который вы хотите включить/disable.
Проблема в исходном коде состоит в том, что тест SFINAE относится только к TA
и TB
, которые являются типами, определенными в структуре inner
, которые содержат problem
.Таким образом, тест зависит только от внешних параметров шаблона (As...
и Bs...
), а не от аргументов шаблона problem
.
Добавление аргумента шаблона со значением по умолчанию для problem
// ..................VVVVVVVVVVVVVVVVV
template<bool dummy, typename UA = TA, typename E = void>
struct problem;
не меняет практического использования самого problem
, но преобразует тест в std::enable_if
template<bool dummy, typename UA>
struct problem<dummy, UA, // ..........VV UA, not TA
std::enable_if_t<(std::tuple_size_v<UA> < std::tuple_size_v<TB>)>>
{ static constexpr auto val() { return 1; } };
в тест, который включает параметр шаблона самого problem
.