Цикл по типам шаблонов - PullRequest
0 голосов
/ 30 июня 2018

У меня есть функция с двумя аргументами шаблона, один для векторного типа данных (int, float, double и т. Д.) И один для целочисленного типа (int, int16_t, uint32_t и т. Д.):

template <typename T, typename I>
void
add(std::vector<T> array, std::vector<I> idx) {
  // ...
}

Для тестов теперь я бы хотел перебрать все возможные комбинации типов данных / целых чисел, например,

// pseudo code
for I in [int, int16_t, int32_t, ...] {
    for T in [float, double, int, int16_t, ...] {
        // create arguments a, b
        add<T, I>(a, b);
    }
}

Можно ли вообще зацикливаться на типах? Как?

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Если у вас есть буст под рукой, тогда boost::hana - определенно лучший способ. Однако не так сложно переопределить эту функцию вручную, если вам необходимо:

#include <iostream>

template<typename... T>
struct iterator {
  template<typename CB_T>
  static void iterate(CB_T const& ) {}
};

template<typename first, typename... rest>
struct iterator<first, rest...> {
  template<typename CB_T>
  static void iterate(CB_T const& cb) {
    cb(first());
    iterator<rest...>::iterate(cb);
  }
};

int main() {
  iterator<int, float>::iterate([](auto const & v_1){
    using v_1_t = decltype(v_1);
    iterator<char, double>::iterate([&](auto const & v_2){
      using v_2_t = decltype(v_2);
      std::cout << typeid(v_1_t).name() << " vs " << typeid(v_2_t).name() << "\n";
    });
  });
  return 0;
}
0 голосов
/ 30 июня 2018

Могут быть более простые способы сделать это, но я бы использовал библиотеку boost hana следующим образом:

#include <boost/hana/for_each.hpp>
#include <boost/hana/tuple.hpp>
#include <vector>
#include <iostream>
#include <boost/type_index.hpp>

namespace hana = boost::hana;

// for example's sake, just print the type
template <typename T, typename I>
void add(std::vector<T> array, std::vector<I> idx) {

    using namespace boost::typeindex;
    std::cout << type_id<T>().pretty_name() << " - " << type_id<I>().pretty_name() << std::endl;
}

int main() {

    auto types1 = hana::tuple_t<int, int16_t, int32_t>;
    auto types2 = hana::tuple_t<float, double, int, int16_t>;

    hana::for_each(types1, [types2](auto t1) {

        hana::for_each(types2, [t1](auto t2) {

            using t1_type = typename decltype(t1)::type;
            using t2_type = typename decltype(t2)::type;

            add<t1_type, t2_type>({}, {});
        });
    });
}
...