24 Haziran 2019 Pazartesi

Variadic Template Unary Right Fold

Giriş
"Her bir eleman için belirtilen lambdayı çalıştır" gibi okumak gerekir.
Metodun imzasında ...,pack şeklinde kullanılır.

Kodda önce bir işlem, daha sonra bir operator ve ardından üç nokta gelir.

Variadic Template Unary Left Fold yazısına da göz atabilirsiniz.

Örnek
Şöyle yaparız. Burada yüm sonuçlar OR'lanarak boolen bir sonuç dünülüyor.
template<class T1, class... Ts>
constexpr bool is_one_of() noexcept {
  return (std::is_same_v<T1, Ts> || ...);
}
Örnek
Şöyle yaparız. Burada yüm sonuçlar OR'lanarak boolen bir sonuç dünülüyor.
template<auto... ts, class T>
constexpr bool
is_magical(const T& t) noexcept(noexcept(((t == ts) || ...))) {
    return ((t == ts) || ...);
}

// usage
if (is_magical<1, 3, 7, 42, 69, 5550123>(x))
Örnek
Belirtilen parametreleri vector'e eklemek için şöyle yaparız.
template<typename T, typename... Args>
void pack(std::vector<uint8_t> &buffer, Args... args) {
  (buffer << args << ...);
}
Çağırmak için şöyle yaparız.
std::vector<uint8_t> buffer;
pack((uint8_t)0xFF, (uint32_t)0x0A, buffer);
Örnek
Şöyle yaparız. update_max diye bir lambda tanımlanıyor. Her bir elemena için lambda çağrılıyor.
template<typename... T>
constexpr size_t max_sizeof(){
  size_t max=0;
  auto update_max = [&max](const size_t& size) {if (max<size) max=size; };
  (update_max(sizeof (T)), ...);
  return max;
}


static_assert(max_sizeof<int, char, double, short>() == 8);
static_assert(max_sizeof<char, float>() == sizeof(float));
static_assert(max_sizeof<int, char>() == 4);
Örnek
Şöyle yaparız. Başa fazladan bir boşluk koyar ama zaten sadece örnek olması için not aldım.
#include <iostream>
#include <string>

template <typename... Args>
void print(Args... args)
{
  std::string sep = " ";
  std::string end = "\n";
  ((std::cout << sep << args), ...);
}

int main()
{
  print(1, 2, 3);
}
Örnek
Vector dizisindeki her bir vectörün tüm eleman için bir metod çağırmak istersek şöyle yaparız.
template <typename F, typename... Vectors>
void for_all_vectors(F&& f, Vectors&&... vs)
{
    (std::for_each(std::forward<Vectors>(vs).begin(), 
                   std::forward<Vectors>(vs).end(), 
                   f), ...);
}
Elimizde A,B,C sınıfları olsun.
class Base { ... }
class DerivedA : public Base { ... }
class DerivedB : public Base { ... }
class DerivedC : public Base { ... }
 Kullanmak için şöyle yaparız.
std::vector<A> my_a;
std::vector<B> my_b;
std::vector<C> my_c;

for_all_vectors([](const auto& x){ something(x); }, my_a, my_b, my_c);

Hiç yorum yok:

Yorum Gönder