20 Kasım 2020 Cuma

Template Specialization - Generic Olmayan Sınıf

Giriş
Sınıfımız generic değildir ancak içindeki bir metod generic yani template kullanıyordur. Burada amaç onlarca farklı parametre tipi için tek bir metod yazmak.

Not : Bu yazının ismi Template Specialization ancak amaç aslında belli bir parametre tipine göre farklı bir metodu çağırmak değil. Amaç aynı işi yapan onlarca farklı parametre tipi için ortam metod yazmak

Örnek
Bu yöntemi çok fazla mesajın dispatch edildiği bir template sınıfında kullandım. .h dosyasında şöyle yaparız. Burada sadece metod generic
template <class T>
void doSomething(const T& * msg);
Daha sonra .cpp dosyasında ortak metodu yazarız. Ortak metod gelen mesajı bir kuyruğa yazıyordu. Gerçi kuyrukta her mesaj tipi için farklı bir metod yine yazılmıştı ama olsun :)
template <class T>
void TClass::doSomething(const T& v) {
  ...
}
Her tip için farklı bir specialization metodunu ortak metodun üstüne tanımlarız. int için şöyle yaparız.
template void TClass::doSomething<int>(const int& v);
long için şöyle yaparız.
template void TClass::doSomething<long>(const long& v);
Örnek
Boost Serialization için A.h dosyasında şöyle yaparız. Burada da A sınıfı generic değil
class A {
public:
  ...
private:
  friend class boost::serialization::access;
  template <class Archive> void serialize(Archive&, unsigned);
};
A.cpp dosyasında şöyle yaparız. Böylece aynı serialize() metodu text_iarchive ve text_oarchive için kullanılabilir.
// A.cpp
#include "A.h"

template <class Archive>
void A::serialize(Archive &ar, unsigned) 
{
    ar & bpt; 
}

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include "B.h" // required at point of instatiation
template void A::serialize(boost::archive::text_iarchive&, unsigned);
template void A::serialize(boost::archive::text_oarchive&, unsigned);
Örnek
Konunun biraz dışında ama not almak istedim. Eğer sınıfımız generic olsaydı ve sadece T1,T2 tipileri için yaratılsaydı cpp dosyasında şöyle yaparız
template void A<T1>::advancedMethod(S1);
template void A<T1>::advancedMethod(S2);
template void A<T2>::advancedMethod(S1);
template void A<T2>::advancedMethod(S2);

Hiç yorum yok:

Yorum Gönder