Tam Sürümünü Görmek İçin : template
quasimodo
04/10/2007, 20:22
template<typename T>
T max(T a, T b)
{
return a > b ? a : b;
}
template<>
const char * max<const char *>( const char * a, const char* b)
{
return (strcmp(a, b) > 0) ? a : b;
}
C++ ta neden boyle bir sey var? Zaten normal islevlerin template lere
gore onceligi var, normal bir islev yazsam daha mantikli degil mi?
Neden bunu tercih edeyim?
Ayrica zaten butun veri tipleri yaziliyor, neden max tan sonra <>
icine neden bir daha const char * yaziliyor?
quasimodo
04/10/2007, 20:24
template<typename T>
void foo(T * ptr, T v = T())
{
* ptr = &val;
}
Boyle bir ilk deger verme nasil oluyor?
template<typename T>
T max(T a, T b)
{
return a > b ? a : b;
}
template<>
const char * max<const char *>( const char * a, const char* b)
{
return (strcmp(a, b) > 0) ? a : b;
}C++ ta neden boyle bir sey var? Zaten normal islevlerin template lere
gore onceligi var, normal bir islev yazsam daha mantikli degil mi?
Neden bunu tercih edeyim?
Ayrica zaten butun veri tipleri yaziliyor, neden max tan sonra <>
icine neden bir daha const char * yaziliyor?
Yazmak zorunda değilsin. Bu da çalışır:
template<typename T>
T max(T a, T b)
{
return a > b ? a : b;
}
template<>
const char * max( const char * a, const char* b)
{
return (strcmp(a, b) > 0) ? a : b;
}Bu kullandığın syntax "Template Specialization"dır. Ama şablonun ne tür bir şablon olduğu önemli.
Şablonlar
-sınıf
-fonksiyon şablonları
olmak üzere 2 çeşittir.
Özelleştirme asıl sınıf şablonları içindir desem çok da yanlış birşey söylemiş olmam sanıyorum. Bu konu hakkında temel bir bilgiyi copy-pastelersek:
// template specialization
#include <iostream>
using namespace std;
// class template:
template <class T>
class mycontainer {
T element;
public:
mycontainer (T arg) {element=arg;}
T increase () {return ++element;}
};
// class template specialization:
template <>
class mycontainer <char> {
char element;
public:
mycontainer (char arg) {element=arg;}
char uppercase ()
{
if ((element>='a')&&(element<='z'))
element+='A'-'a';
return element;
}
};
int main () {
mycontainer<int> myint (7);
mycontainer<char> mychar ('j');
cout << myint.increase() << endl;
cout << mychar.uppercase() << endl;
return 0;
}
8
J
This is the syntax used in the class template specialization:
template <> class mycontainer <char> { ... };
First of all, notice that we precede the class template name with an emptytemplate<> parameter list. This is to explicitly declare it as a template specialization.
But more important than this prefix, is the <char> specialization parameter after the class template name. This specialization parameter itself identifies the type for which we are going to declare a template class specialization (char). Notice the differences between the generic class template and the specialization:
template <class T> class mycontainer { ... };
template <> class mycontainer <char> { ... };
The first line is the generic template, and the second one is the specialization.
When we declare specializations for a template class, we must also define all its members, even those exactly equal to the generic template class, because there is no "inheritance" of members from the generic template to the specialization.
Kaynak: http://www.cplusplus.com/doc/tutorial/templates.html
Tabi bu sınıf şablonu özelleştirme için kullanılan syntax'ı fonksiyon şablonları için de kullanabilirsin ama bu kodunu biraz karmaşıklaştıracaktır. Fonksiyon şablonları için özelleştirme kullanmamak faydalı olabilir. Sana güzel bir link vereceğim bu konu ile ilgili.
Tıkla:
Why Not Specialize Function Templates? (http://www.gotw.ca/publications/mill17.htm)
İkinci sorunda tam olarak neyi kastettiğini anlamadım.
acehreli
05/10/2007, 00:08
Orada parametrenin adi 'v' degil de 'val' olacak tabii.
Fonksiyon parametrelerine varsayilan deger verebiliriz ya; ornegin
void bar(int i = 42);
dedigimizde; bar'i parametresiz cagirinca i'nin degeri 42 olur ya... Iste ayni sekilde, senin foo islevini de 'val' olmadan cagirirsak onun degeri T() oluyor.
T()'nin anlami da, "T turunun varsayilan degeri"dir:
Temel turler icin: 0
POD (plain old data) turler icin: butun bitleri 0
Kullanici turleri icin: o tUrUn varsayilan kurucusu ile kurulan degeri (nesnesi)
Ali
quasimodo
05/10/2007, 22:03
template<typename T>
void foo(T * ptr, T val = T())
{
* ptr = &val;
}
foo(5);
dedik diyelim val = 0 oldu, ptr nin icerigine val in adres degeri
atamiyormu burada?
* ptr = &val;
yerine acaba
ptr = &val;
mi olmali?
Euclides
05/10/2007, 22:29
her 2 türlüde bence mantıksız bir kod.
*ptr = &val;
olduğu düşünelim. "val"'ın adresi out of scope'da anlamını yiğtirecektir.
ptr = &val;
hem ptr hemde val out of scope'da anlamsızdır.
evet öyle olması gerektiği gibi,
foo(5) satırında
foo'ya parametre olarak sabit değil, pointer geçirmelisin.
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.