February 16th Monday 2009 (二月 十六日 月曜日)
2009-02-26 11:26
537 查看
Template Specializations
Implicit Instantiations
ArrayTb<int, 100> stuff; // implicit instantiation
The compiler doesn't generate an implicit instantiation of the class until it needs an object:
ArrayTb<double, 30> * pt; // a pointer, no object needed yet
pt = new ArrayTb<double, 30>; // now an object is needed
Explicit Instantiations
The compiler generates an explicit instantiation of a class declaration when you declare a class using the
keyword template and indicating the desired type or types. The declaration should be in the same namespace as
the template definition. For example, the declaration
template class ArrayTb<String, 100>; // generate ArrayTB<String, 100> class
In this case the compiler generates the class definition, including method definitions, even though no object
of the class has yet been created or mentioned. Just as with the implicit instantiation, the general template is
used as a guide to generate the specialization.
Explicit Specializations
A specialized class template definition has the following form:
template <> class Classname<specialized-type-name> { ... };
template <> class SortedArray<char *>
{
...// details omitted
};
SortedArray<int> scores; // use general definition
SortedArray<char *> dates; // use specialized definition
Partial Specializations
// general template
template <class T1, class T2> class Pair {...};
// specialization with T2 set to int
template <class T1> class Pair<T1, int> {...};
// specialization with T1 and T2 set to int
template <> class Pair<int, int> {...};
Pair<double, double> p1; // use general Pair template
Pair<double, int> p2; // use Pair<T1, int> partial specialization
Pair<int, int> p3; // use Pair<int, int> explicit specialization
// general template
template <class T1, class T2, class T3> class Trio{...};
// specialization with T3 set to T2
template <class T1, class T2> class Trio<T1, T2, T2> {...};
// specialization with T3 and T2 set to T1*
template <class T1> class Trio<T1, T1*, T1*> {...};
Trio<int, short, char *> t1; // use general template
Trio<int, short> t2; // use Trio<T1, T2, T2>
Trio<char, char *, char *> t3; use Trio<T1, T1*, T1*>
Member Templates
// tempmemb.cpp -- template members
#include <iostream>
using namespace std;
template <typename T>
class beta
{
private:
template <typename V> // nested template class member
class hold
{
private:
V val;
public:
hold(V v = 0) : val(v) {}
void show() const { cout << val << endl; }
V Value() const { return val; }
};
hold<T> q; // template object
hold<int> n; // template object
public:
beta( T t, int i) : q(t), n(i) {}
template<typename U> // template method
U blab(U u, T t) { return (n.Value() + q.Value()) * u / t; }
void Show() const {q.show(); n.show();}
};
int main()
{
beta<double> guy(3.5, 3);
guy.Show();
cout << guy.blab(10, 2.3) << endl;
cout << "Done/n";
return 0;
}
Or another way define a memeber template.
template <typename T>
class beta
{
private:
template <typename V> // declaration
class hold;
hold<T> q;
hold<int> n;
public:
beta( T t, int i) : q(t), n(i) {}
template<typename U> // declaration
U blab(U u, T t);
void Show() const {q.show(); n.show();}
};
// member definition
template <typename T>
template<typename V>
class beta<T>::hold
{
private:
V val;
public:
hold(V v = 0) : val(v) {}
void show() const { cout << val << endl; }
V Value() const { return val; }
};
// member definition
template <typename T>
template <typename U>
U beta<T>::blab(U u, T t)
{
return (n.Value() + q.Value()) * u / t;
}
The definitions have to identify T, V, and U as template parameters. Because the templates are nested, you have
to use the
template <typename T>
template <typename V>
syntax instead of the
template<typename T, typename V>
syntax.
Templates As Parameters
// tempparm.cpp -- template template parameters
#include <iostream>
using namespace std;
#include "stacktp.h"
template <template <typename T> class Thing>
class Crab
{
private:
Thing<int> s1;
Thing<double> s2;
public:
Crab() {};
// assumes the thing class has push() and pop() members
bool push(int a, double x) { return s1.push(a) && s2.push(x); }
bool pop(int & a, double & x){ return s1.pop(a) && s2.pop(x); }
};
int main()
{
Crab<Stack> nebula;
// Stack must match template <typename T> class thing
int ni;
double nb;
while (cin>> ni >> nb && ni > 0 && nb > 0)
{
if (!nebula.push(ni, nb))
break;
}
while (nebula.pop(ni, nb))
cout << ni << ", " << nb << endl;
cout << "Done./n";
return 0;
}
The Thing<int> is instantiated as Stack<int> and Thing<double> is instantiated as Stack<double>. In short,
the template parameter Thing is replaced by whatever template type is used as a template argument in declaring
a Crab object.
Implicit Instantiations
ArrayTb<int, 100> stuff; // implicit instantiation
The compiler doesn't generate an implicit instantiation of the class until it needs an object:
ArrayTb<double, 30> * pt; // a pointer, no object needed yet
pt = new ArrayTb<double, 30>; // now an object is needed
Explicit Instantiations
The compiler generates an explicit instantiation of a class declaration when you declare a class using the
keyword template and indicating the desired type or types. The declaration should be in the same namespace as
the template definition. For example, the declaration
template class ArrayTb<String, 100>; // generate ArrayTB<String, 100> class
In this case the compiler generates the class definition, including method definitions, even though no object
of the class has yet been created or mentioned. Just as with the implicit instantiation, the general template is
used as a guide to generate the specialization.
Explicit Specializations
A specialized class template definition has the following form:
template <> class Classname<specialized-type-name> { ... };
template <> class SortedArray<char *>
{
...// details omitted
};
SortedArray<int> scores; // use general definition
SortedArray<char *> dates; // use specialized definition
Partial Specializations
// general template
template <class T1, class T2> class Pair {...};
// specialization with T2 set to int
template <class T1> class Pair<T1, int> {...};
// specialization with T1 and T2 set to int
template <> class Pair<int, int> {...};
Pair<double, double> p1; // use general Pair template
Pair<double, int> p2; // use Pair<T1, int> partial specialization
Pair<int, int> p3; // use Pair<int, int> explicit specialization
// general template
template <class T1, class T2, class T3> class Trio{...};
// specialization with T3 set to T2
template <class T1, class T2> class Trio<T1, T2, T2> {...};
// specialization with T3 and T2 set to T1*
template <class T1> class Trio<T1, T1*, T1*> {...};
Trio<int, short, char *> t1; // use general template
Trio<int, short> t2; // use Trio<T1, T2, T2>
Trio<char, char *, char *> t3; use Trio<T1, T1*, T1*>
Member Templates
// tempmemb.cpp -- template members
#include <iostream>
using namespace std;
template <typename T>
class beta
{
private:
template <typename V> // nested template class member
class hold
{
private:
V val;
public:
hold(V v = 0) : val(v) {}
void show() const { cout << val << endl; }
V Value() const { return val; }
};
hold<T> q; // template object
hold<int> n; // template object
public:
beta( T t, int i) : q(t), n(i) {}
template<typename U> // template method
U blab(U u, T t) { return (n.Value() + q.Value()) * u / t; }
void Show() const {q.show(); n.show();}
};
int main()
{
beta<double> guy(3.5, 3);
guy.Show();
cout << guy.blab(10, 2.3) << endl;
cout << "Done/n";
return 0;
}
Or another way define a memeber template.
template <typename T>
class beta
{
private:
template <typename V> // declaration
class hold;
hold<T> q;
hold<int> n;
public:
beta( T t, int i) : q(t), n(i) {}
template<typename U> // declaration
U blab(U u, T t);
void Show() const {q.show(); n.show();}
};
// member definition
template <typename T>
template<typename V>
class beta<T>::hold
{
private:
V val;
public:
hold(V v = 0) : val(v) {}
void show() const { cout << val << endl; }
V Value() const { return val; }
};
// member definition
template <typename T>
template <typename U>
U beta<T>::blab(U u, T t)
{
return (n.Value() + q.Value()) * u / t;
}
The definitions have to identify T, V, and U as template parameters. Because the templates are nested, you have
to use the
template <typename T>
template <typename V>
syntax instead of the
template<typename T, typename V>
syntax.
Templates As Parameters
// tempparm.cpp -- template template parameters
#include <iostream>
using namespace std;
#include "stacktp.h"
template <template <typename T> class Thing>
class Crab
{
private:
Thing<int> s1;
Thing<double> s2;
public:
Crab() {};
// assumes the thing class has push() and pop() members
bool push(int a, double x) { return s1.push(a) && s2.push(x); }
bool pop(int & a, double & x){ return s1.pop(a) && s2.pop(x); }
};
int main()
{
Crab<Stack> nebula;
// Stack must match template <typename T> class thing
int ni;
double nb;
while (cin>> ni >> nb && ni > 0 && nb > 0)
{
if (!nebula.push(ni, nb))
break;
}
while (nebula.pop(ni, nb))
cout << ni << ", " << nb << endl;
cout << "Done./n";
return 0;
}
The Thing<int> is instantiated as Stack<int> and Thing<double> is instantiated as Stack<double>. In short,
the template parameter Thing is replaced by whatever template type is used as a template argument in declaring
a Crab object.
相关文章推荐
- February 23th Monday 2009 (二月 二十三日 月曜日)
- February 2nd Monday 2009 (二月 二日 月曜日)
- 2009 March 16th Monday (三月 十六日 月曜日)
- February 9th Monday 2009 (二月 九日 月曜日)
- July 16th Monday (七月 十六日 月曜日)
- 2008 February 4th Monday (二月 四日 月曜日)
- Aprial 16th Monday (四月 十六日 月曜日)
- 2008 February 25th Monday (二月 二十五日 月曜日)
- 2008 February 18th Monday (二月 十八日 月曜日)
- January 19th Monday 2009 (一月 十九日 月曜日)
- February 6th Friday 2009 (二月 六日 金曜日)
- February 18th Wednesday 2009 (二月 十八日 水曜日)
- February 5th Monday (一月 五日 月曜日)
- February 12th Thursday 2009 (二月 十二日 木曜日)
- 2009 March 30th Monday (三月 三十日 月曜日)
- January 12th Monday 2009 (一月 十二日 月曜日)
- February 11th Wednesday 2009 (二月 十一日 水曜日)
- February 20th Friday 2009 (二月 二十日 金曜日)
- February 10th Tuesday 2009 (二月 十日 火曜日)
- February 26th Thursday 2009 (二月 二十六日 木曜日)