编辑鉴于一个空的变体(std::variant<>)的格式不正确(根据cppreference),应该使用它std::variant<std::monostate>代替,我修改了答案(tuple2variant()为空元组添加了专门化),以支持类型为V1或V2为空的情况。
这有点decltype()del妄,但是...如果您按如下方式声明一个辅助过滤器函数对,
template <bool B, typename T>
constexpr std::enable_if_t<B == std::is_arithmetic_v<T>, std::tuple<T>>
   filterArithm ();
template <bool B, typename T>
constexpr std::enable_if_t<B != std::is_arithmetic_v<T>, std::tuple<>>
   filterArithm ();
和元组到变体函数(专门针对空元组,以避免empty std::variant)
std::variant<std::monostate> tuple2variant (std::tuple<> const &);
template <typename ... Ts>
std::variant<Ts...> tuple2variant (std::tuple<Ts...> const &);
您的班级简单地(?)成为
template <typename ... Ts>
struct TheAnswer<std::variant<Ts...>>
 {
   using V1 = decltype(tuple2variant(std::declval<
                 decltype(std::tuple_cat( filterArithm<true, Ts>()... ))>()));
   using V2 = decltype(tuple2variant(std::declval<
                 decltype(std::tuple_cat( filterArithm<false, Ts>()... ))>()));
 };
如果您想要更通用的东西(如果要std::arithmetic作为模板参数传递),则可以修改filterArithm()传递模板模板过滤器参数F(重命名filterType())的函数。
template <template <typename> class F, bool B, typename T>
constexpr std::enable_if_t<B == F<T>::value, std::tuple<T>>
   filterType ();
template <template <typename> class F, bool B, typename T>
constexpr std::enable_if_t<B != F<T>::value, std::tuple<>>
   filterType ();
该TheAnswer班成为
template <typename, template <typename> class>
struct TheAnswer;
template <typename ... Ts, template <typename> class F>
struct TheAnswer<std::variant<Ts...>, F>
 {
   using V1 = decltype(tuple2variant(std::declval<decltype(
                 std::tuple_cat( filterType<F, true, Ts>()... ))>()));
   using V2 = decltype(tuple2variant(std::declval<decltype(
                 std::tuple_cat( filterType<F, false, Ts>()... ))>()));
 };
和TA宣言还采取std::is_arithmetic
using TA = TheAnswer<std::variant<bool, char, std::string, int, float,
                                  double, std::vector<int>>,
                     std::is_arithmetic>;
下面是一个完整的编译示例,带有std::is_arithmeticas参数和一个V2空的case
#include <tuple>
#include <string>
#include <vector>
#include <variant>
#include <type_traits>
std::variant<std::monostate> tuple2variant (std::tuple<> const &);
template <typename ... Ts>
std::variant<Ts...> tuple2variant (std::tuple<Ts...> const &);
template <template <typename> class F, bool B, typename T>
constexpr std::enable_if_t<B == F<T>::value, std::tuple<T>>
   filterType ();
template <template <typename> class F, bool B, typename T>
constexpr std::enable_if_t<B != F<T>::value, std::tuple<>>
   filterType ();
template <typename, template <typename> class>
struct TheAnswer;
template <typename ... Ts, template <typename> class F>
struct TheAnswer<std::variant<Ts...>, F>
 {
   using V1 = decltype(tuple2variant(std::declval<decltype(
                 std::tuple_cat( filterType<F, true, Ts>()... ))>()));
   using V2 = decltype(tuple2variant(std::declval<decltype(
                 std::tuple_cat( filterType<F, false, Ts>()... ))>()));
 };
int main ()
 {
   using TA = TheAnswer<std::variant<bool, char, std::string, int, float,
                                     double, std::vector<int>>,
                        std::is_arithmetic>;
   using TB = TheAnswer<std::variant<bool, char, int, float, double>,
                        std::is_arithmetic>;
   using VA1 = std::variant<bool, char, int, float, double>;
   using VA2 = std::variant<std::string, std::vector<int>>;
   using VB1 = VA1;
   using VB2 = std::variant<std::monostate>;
   static_assert( std::is_same_v<VA1, TA::V1> );
   static_assert( std::is_same_v<VA2, TA::V2> );
   static_assert( std::is_same_v<VB1, TB::V1> );
   static_assert( std::is_same_v<VB2, TB::V2> );
 }
               
              
Types...内部包装?std::variant