c++ 使用类型名组合调用模板函数

tjvv9vkg  于 2023-02-26  发布在  其他
关注(0)|答案(2)|浏览(125)

我想循环遍历一个“类型名列表”,查看它们的所有组合。我想使用一个元组来完成这个任务,compare:

template<typename T, typename R>
void foo() {
    std::cout << std::numeric_limits<T>::max() << ", " << std::numeric_limits<R>::max();
}

void call() {
    using int_types = std::tuple<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t>;
    //Just to visualize my idea, this code does not work! (see comments)
    constexpr auto indices = std::make_integer_sequence<size_t, 8>();
    for (auto i: indices) {
        using T = std::tuple_element_t<i, int_types>;
        for (auto j: indices) {
            using R = std::tuple_element_t<j, int_types>;
            foo<T, R>();
        }
    }
}

当然for循环不是consteval的,所以这个方法不起作用,我想用STL中的递归或者一些consteval的东西可能会起作用,但是我不太明白。

h43kikqp

h43kikqp1#

你可以用这种方式扩展包

using int_types = std::tuple<int8_t, uint8_t, int16_t, uint16_t,
                             int32_t, uint32_t, int64_t, uint64_t>;

[]<typename... Ts>(std::tuple<Ts...>){
    ([]<typename T, typename... Us>(std::type_identity<T>, std::tuple<Us...>){
        (foo<T, Us>(), ...);
    }(std::type_identity<Ts>{}, int_types{}), ...);
}(int_types{});

Demo

gijlo24d

gijlo24d2#

这是一个基于索引的版本,其中内部lambda可以访问具体的索引,这里是LK,如果你想在索引相等的情况下排除对foo的调用,你可以进行验证,例如:

void call() {
   using int_types = std::tuple<int8_t, uint8_t, int16_t, uint16_t, int32_t,
                                uint32_t, int64_t, uint64_t>;

   constexpr auto tsize = std::tuple_size_v<int_types>;

   []<std::size_t... Is>(std::index_sequence<Is...>) {
      (  // fold 1
         []<size_t I, std::size_t... Js>(std::integral_constant<std::size_t, I>,
                                         std::index_sequence<Js...>) 
         {
            ( // fold 2:
               []<std::size_t K, std::size_t L>(
                   std::integral_constant<std::size_t, K>,
                   std::integral_constant<std::size_t, L>)
               {
                        
                  if constexpr(K != L) foo<std::tuple_element_t<K, int_types>,
                                           std::tuple_element_t<L, int_types>>();

               }(std::integral_constant<std::size_t, I>(),
                 std::integral_constant<std::size_t, Js>()),
               ...);

         }(std::integral_constant<std::size_t, Is>(),
           std::make_index_sequence<tsize>()),
         ...);
   }(std::make_index_sequence<tsize>());
}

Demo

相关问题