简体   繁体   English

遍历模板int

[英]Iterate over template int

I have a function: 我有一个功能:

template<class Real, int N>
constexpr std::array<Real, N> get_array();

and I would like to test it over many types and many integers. 我想对许多类型和整数进行测试。 In pseudocode: 用伪代码:

auto types = {float, double, long double};
for(int i = 0; i < 25; ++i) {
   for (type : types) {
        auto arr = get_array<type, i>();
        // test arr
   }
}

Obviously this doesn't compile. 显然,这无法编译。 Is there a way to patch up the loop to make it so I can iterate over the array? 有没有一种方法可以修补循环,以使之可以遍历数组?

Since you have Boost.Hana tagged anyway, we can just use it: 由于您已经标记了Boost.Hana,因此我们可以使用它:

auto types = hana::tuple_t<float, double, long double>;
hana::for_each(types, [](auto type){
    hana::for_each(std::make_index_sequence<25>(), [=](auto idx){
        // here type is an object that denotes the type and
        // idx is an integral constant that denotes the next value

        get_array<typename decltype(type)::type, idx>();
    });
});

The accepted answer is good, but if you don't want to pollute your call stack, it is better to do all of the processing that you can before you get to the actual run-time stuff. 可接受的答案是好的,但是如果您不想污染您的调用堆栈,那么最好在获得实际运行时之前进行所有可能的处理。

The example here is using hana::cartesian_product which is probably overkill for ad hoc use cases, but you could use nested hana::unpack s to get the same effect. 这里的示例使用的是hana::cartesian_product ,对于临时用例来说可能是多余的,但是您可以使用嵌套的hana::unpack来获得相同的效果。

Here is a working example: 这是一个工作示例:

https://godbolt.org/z/zKwpqe https://godbolt.org/z/zKwpqe

#include <array>
#include <boost/hana/assert.hpp>
#include <boost/hana/at.hpp>
#include <boost/hana/cartesian_product.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/for_each.hpp>
#include <boost/hana/range.hpp>
#include <boost/hana/transform.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/type.hpp>

namespace hana = boost::hana;

template <typename Real, int N>
constexpr std::array<Real, N> get_array() {
  return {};
}

int main() {
  auto types   = hana::tuple_t<float, double, long, double>;
  auto lengths = hana::to_tuple(hana::range_c<int, 0, 4>);
  auto tls = hana::cartesian_product(hana::make_tuple(types, lengths));
  auto get_array_fns = hana::transform(tls, [](auto pair) {
    return [] {
      return get_array<typename decltype(+hana::at_c<0>(pair))::type,
                       decltype(+hana::at_c<1>(pair))::value>();
      };
  });

  hana::for_each(get_array_fns, [](auto get_array) {
    auto arr = get_array();
    // test arr 
  });

  auto result_types = hana::unpack(get_array_fns, [](auto ...get_array) {
    return hana::tuple_t<decltype(get_array())...>;
  });

  BOOST_HANA_CONSTANT_CHECK(hana::equal(
    decltype(result_types){},
    hana::tuple_t<std::array<float,  0>,
                  std::array<float,  1>,
                  std::array<float,  2>,
                  std::array<float,  3>,
                  std::array<double, 0>,
                  std::array<double, 1>,
                  std::array<double, 2>,
                  std::array<double, 3>,
                  std::array<long,   0>,
                  std::array<long,   1>,
                  std::array<long,   2>,
                  std::array<long,   3>,
                  std::array<double, 0>,
                  std::array<double, 1>,
                  std::array<double, 2>,
                  std::array<double, 3>>));
}

What about as follows (without boost)? 怎么办(不加价)?

#include <array>
#include <iostream>

template <typename T, std::size_t Dim>
constexpr std::array<T, Dim> get_array ()
 { return {}; }

// fake test
template <typename T, std::size_t Dim>
constexpr bool checkArray (std::array<T, Dim> const &)
 { return true; }

template <typename T, std::size_t ... Is>
constexpr bool checkSequence (std::index_sequence<Is...> const &)
 { return (... && checkArray(get_array<T, Is>())); }

template <typename ... Ts>
constexpr bool checkTypes ()
 { return (... && checkSequence<Ts>(std::make_index_sequence<25u>{})); }

int main ()
 {
   constexpr auto value = checkTypes<float, double, long double>();

   std::cout << value << std::endl;
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM