typeid(T).name()
, yazının insan tarafından anlaşılabilir adını döndürmediğinden, şablon argümanlarının adını bir sınıfa yazdırmak istiyorsak bize fazla yardımcı olmaz şablon, özellikle hata ayıklama yaptığımızda. Sık sık hata ayıklama bu yazma gibi hissediyorum: Tüm şablon bağımsız değişkenleriyle birlikte güzel yazdırma türleri ve sınıf şablonu
print<Args...>(cout); //dump the names of all types to stdout!
yüzden bana sınıf şablonunun adını verir oldukça desenli programı yazıyorum. Eh, bazı örnek kullanımı yoluyla bunu anlamak kolaydır: Dahili olarak
print<int>(cout); //prints int
print<int, double, char>(cout); //prints int, double, char
print<std::string>(cout); //prints std::basic_string<char, .. etc>
print<std::wstring>(cout); //prints std::basic_string<wchar_t, .. etc>
print<X<int,Y<int>>>(cout); //prints X<int, Y<int>>
, ben şablon argüman olarak kendisine Y<int>
geçerken bana "Y"
döndüren template_name
adında bir sınıf şablonunu kullanıyorum. Her kullanıcı sınıfı şablonu için kısmen uzmanlaşmıştır.
#define DEFINE_TEMPLATE_NAME(template_type) \
template<typename ... Ts>\
struct template_name<template_type<Ts...>>\
{\
static const char* name()\
{\
return #template_type;\
}\
};
Ve kullanıcı
onun şablon sınıfı kaydetmek için bu makro kullanmak için gereklidir gibidir: uzmanlaşmatemplate_name<template_type<Ts...>>
bunu demek
türlerinde sadece üzerinde variadic sınıf şablonu, çünkü işleri
DEFINE_TEMPLATE_NAME(std::basic_string);
DEFINE_TEMPLATE_NAME(std::vector);
DEFINE_TEMPLATE_NAME(X); //X is a class template
DEFINE_TEMPLATE_NAME(Y); //Y is a class template
10 tüm şablon parametreleri türleri türleri olduğu sürece, sınıf şablonunun adı dönecektir. Aynı zamanda hem fonksiyon-tiplerini ve üye fonksiyonlu-tiplerini baskı yapabiliyor:
typedef void fun(int,int);
//lets use snl::name() which returns name instead of printing!
std::cout << snl::name<fun>(); //prints : void(int,int)
std::cout << snl::name<fun*>(); //prints : void(*)(int,int)
diğer dakikalık detayları ile the working code here bakınız. Şimdiye kadar harika çalışıyor.
Ama şimdi bu konuda iyileştirilmesi ve sivil türleri argümanlar sablona desteği eklemek istediğiniz ediyorum ve de karışık şablon argümanları:
template<int...>
struct Z{};
//non-type template arguments : 1,2,3
snd::print<Z<1,2,3>>(cout); //should print Z<1,2,3>
//mixed template arguments : int, 100
snd::print<std::array<int,100>>(cout); //should print std::array<int,100>
Bunu nasıl yapardın? Böyle bir sınıf şablonunun ve argümanlarının adını genel olarak nasıl alabilirim?
GCC, oldukça kullanışlı şablon sınıf adlarını yazdıran bir demangler ... –
@KerrekSB: Evet, ama bu standart değil. Her yerde çalışan bir şey istiyorum. – Nawaz