13 Nisan 2018 Cuma

Variadic Template C++11

Giriş
C++11 ile variadic template özyinelemeli çalışır.

Örnek
Verilen her parametrenin [0-16] arasında olduğunu kontrol etmek için şöyle yaparız.
bool check(int a) {
  return 0 <= a && a < 16;
}   

template<typename... Args>
bool check(int a, Args... args) {
  return check(a) && check(args...);
}
Örnek
Verilen sayıları çarpmak için şöyle yaparız.
template<size_t... N_i>
struct product { 
  static const size_t value = 1; 
};

template<size_t N_1, size_t... N_i>
struct product<N_1, N_i...> {
  static const size_t value = N_1 * product<N_i...>::value;
};

std::array< float, product<N_i...>::value> arr;
Örnek
Eğer bir sayı ile çağırıyorsak 0 olunca duran kodu yazmak gerekir.
template<typename T, unsigned N, typename... REST>
struct generate_tuple_type
{
 typedef typename generate_tuple_type<T, N-1, T, REST...>::type type;
};

template<typename T, typename... REST>
struct generate_tuple_type<T, 0, REST...>
{
  typedef std::tuple<REST...> type;
};
Bu kod bize bir std::tuple döndürür.
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" );
Örnek
Şöyle yaparız. sizeof...(args) şeklinde kullanım ile parametre sayısı anlaşılıyor.
template <class A, class... Args>
void print(A arg, Args... args) {
  std::cout << arg;
  if constexpr (sizeof...(Args) > 0) {
    std::cout << sep;
    print(args...);
  }
}
Örnek
Kaç tane paramete geçtiğini anlamak için şöyle yaparız.
[](auto...p){return sizeof...(p);}
Örnek
Bu örnekte variadic  template kullanarak kalıtım gösteriliyor. Verilen tip kadar üye alana yarartmak için şöyle yaparız.
template<typename... Members>
class Composition;

template<typename FirstMember, typename... MoreMembers>
class Composition<FirstMember, MoreMembers...>
    : public Composition<MoreMembers...> {
protected:
    FirstMember member;
};

template<typename FirstMember>
class Composition<FirstMember>
{
protected:
    FirstMember member;
};
Şöyle yaparız.
Composition<Composition<
    Composition<int>, Composition<int>*>, double> composition;


Hiç yorum yok:

Yorum Gönder