6 Aralık 2019 Cuma

std::integer_sequence

Giriş
std::index_sequence ile kardeştir. std::integer_sequence yaratmak için std::make_index_sequence kullanılır

Kullanım Amacı
Elimizde şöyle bir kod olsun
template <size_t N>
class A {
  template <size_t N>
  someFunctions(){};
}
Bu kodu döngü içinde çağırmak isteyelim. Ancak bunu başaramayız çünkü template kodların derleme zamanında belirli sabitler olması istenir. Bu durumda std::integer_sequence kullanılır
/ in main()
for (int i = 1; i <= 100; i++) {
  const int N = i;  // dont know how to do this
  A<N> a;
  a.functionCalls();
}
Örnek
Şöyle yaparız. std::cout her bir değeri için çağrılır
a#include <utility>
#include <iostream>

auto y = std::integer_sequence<unsigned, 9, 4, 3, 8>{};
auto z = std::integer_sequence<int, 0, 1, 2, 3>{};

template<typename T, T... ints>
void print_sequence(std::integer_sequence<T, ints...> int_seq)
{
  std::cout << "The sequence of size " << int_seq.size() << ": ";
  ((std::cout << ints << ' '), ...);
  std::cout << '\n';
}

int main(int, char**)
{
  print_sequence(y);
  print_sequence(z);
  return 0;
}

Örnek
Elmizde şöyle bir kod olsun. f() metodu her bir değer için çağrılır
template <typename T, T... S, typename F>
constexpr void for_sequence(std::integer_sequence<T, S...>, F f) {
    (static_cast<void>(f(std::integral_constant<T, S>{})), ...);
}
Açıklaması şöyle.
This function takes an integer sequence and instantiate the lambda F as many time as the length of the sequence.

Çağırmak için şöyle yaparız.
for_sequence(std::make_index_sequence<100>(), [](auto N) { /* N is from 0 to 99 */
  A<N + 1> a; /* N + 1 is from 1 to 100 */
  a.functionCalls();
});
Örnek
Elimizde generate_tuple diye bir kod olsun ve std::tuple nesnesini bizim için kolayca tanımlasın.
Yani şu kod true dönsün istiyoruz.
int main()
{
  using gen_tuple_t = generate_tuple_type<int, 3>::type;
  using hand_tuple_t = std::tuple<int, int, int>;
  static_assert( std::is_same<gen_tuple_t, hand_tuple_t>::value, "different" );
}
Şöyle yaparız.
template <typename T, size_t N>
class generate_tuple_type {
    template <typename = std::make_index_sequence<N>>
    struct impl;

    template <size_t... Is>
    struct impl<std::index_sequence<Is...>> {
        template <size_t >
        using wrap = T;

        using type = std::tuple<wrap<Is>...>;
    };

public:
    using type = typename impl<>::type;
};




Hiç yorum yok:

Yorum Gönder