C++泛型编程 - template模板

 

 

泛型编程就是以独立于任何特定类型的方式编写代码,而模板是C++泛型编程的基础.

所谓template,是针对“一个或多个尚未明确的类型”所编写的函数或类.

使用template时,可以显示的或隐示的将类型当作参数来传递.

下面是一个典型的例子,传回两数中的较大者:

template < class T >
inline const T & MAX( const T & a , const T & b)
{
    return a >b ? a:b;
}

在这里,第一行将T定义为任意数据类型,于函数被调用时由调用者指定.

这个类型有关键字class引导,也可用typename引导,typename其实比class更直观.

(需要注意的是,如果用到了嵌套依赖类型,则必须要用到typename).

理解

  第一行template<class T>告诉编译器:我在这儿定义了一个可变类型T,调用者使用什么类型你就怎么编译吧!

缺省模板参数

template class可以有缺省参数,例如一下声明,允许你使用一个或多个template来声明MyClass对象:

template < class T , class container = vector < T > >
class MyClass
{
public :
      MyClass (){}
      ~ MyClass (){}
protected :
private :
};

如果只传递一个参数,那么缺省参数可作为第二参数使用:

MyClass < int > x1; // equivalent to:
MyClass < int , vector < int > > x2;

 注意:template缺省参数根据前一个(或前一些)参数而定义。这也就意味着如果参数传递列表中某个参数是缺省参数,那么后面的所有参数都应该是缺省参数.

关键字typename

关键字typename被用来做为类型之前的标识符号。考虑下面例子:

template < class SubType >
struct BaseType
{
      SubType a;
};

template < class T >
class MyClass1
{
      typename T :: SubType * ptr;
      // ...
};

这里,typename指出SubType是class T中定义的一个类型,因此ptr是一个指向T::SubType的指针.

如果没有typename,SubType将会被当成一个static成员,于是:

T::SubType * ptr;

会被解释为类型T中的两个子成员SubType和ptr的乘积.

成员模板

class成员函数可以是个template,但是这样的成员template类型既不能是virtual,也不能有缺省参数,例如:

class MyClass
{
      //...
      template < class T >
      void f( T);
};

在这里,MyClass::f声明了一个成员函数,适用于任何类型参数.

这个特性常用来为template class中的成员提供自动类型转换,例如下面的例子中,assign()的参数x,其类型必须和调用端所提供的对象的类型完全吻合:

template < class T >
class MyClass
{
public :
      MyClass();
      ~ MyClass();
      void assign( const MyClass < T >& x) // x must have same type as *this
      {
            value = x . value;
      }
      // ...
protected :
private :
      T value;
};

如果使用了两个类型,即使两个类型之间可以自动转换,也会出错:

void fun()
{
      MyClass < double > d;
      MyClass < int > i;

      d . assign( d); // OK
      d . assign( i); // ERROR: i is MyClass<int> but MyClass<double> is required
}

理解

  对于一个template class中的template成员,遵循“先入为主”,如果第一次指定了类型,那么后面都要和第一次保持一致.

但如果要指定两个不同类型的类成员变量怎么办呢?

方法很简单,我们将成员变量在使用一个和class不同的template类型就行:

template < class T >
class MyClass
{
public :
      MyClass();
      ~ MyClass();
      template < class X > // member template
      void assign( const MyClass < X >& x) // allow different template types
      {
            value = x . getValu();
      }
      T getValue() const
      {
            return value;
      }
      // ...
protected :
private :
      T value;
};

void fun()
{
      MyClass < double > d;
      MyClass < int > i;
     
      d . assign( d); // OK
      i . assign( i); // OK (int is assigned to double)
}

 

转载请注明出处:http://www.cnblogs.com/crazyacking/p/4997425.html ,侵权必究.

你可能感兴趣的:(C++泛型编程 - template模板)