C++成员模板

C++中的模板是很强大的,众所周知的有函数模板,类模板。而在类里面,我们还可以嵌套定义成员模板(包括模板类,模板函数/方法)。

在《C++ Prime Plus》一书中,有一个经典的例子如下:

#include <iostream>

using std::cout;
using std::endl;

template <typename T>
class beta {
private:
  /* data */
  template <typename V>       // nested template class member
  class hold {
  private:
    /* data */
    V val;

  public:
    hold (V v = 0) : val(v) {} ;
    void show() const { cout << val << endl; }
    V value() const { return val; }
    virtual ~hold () { }
  };

  // template object
  hold<T> q;
  hold<int> n;

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();
  }
  virtual ~beta () { }
};

这个类的定义如上(见《C++ Prime Plus》14.20)。

成员模板-模板类

在上例中,在模板类beta中嵌套定义了private的模板类hold,类hold将作为类beta的成员,在外部不可见。beta中初始化的两个hold模板对象,第一个对象q的模板参数即为外层类的模板参数T,而第二个对象n的模板参数使用int。

成员模板-模板方法(类似模板函数)

在外层模板类beta中,我们定义的模板方法blab,blab与单独定义的模板函数类似。在此处,模板方法blab具有一个独立的模板参数U,U的类型将在调用blab方法时由其第一个参数决定。blab返回值的类型也是U。

成员模板-将实现(原型与定义分离)放在类的外部

我们可以将嵌套的模板类和模板方法放在外层类的外部,因此模板类hold和模板方法blab的实现可以为:

// member definition
template <typename T>
template <typename V>       // nested template class member
class beta<T>::hold {
private:
  /* data */
  V val;

public:
  hold (V v = 0) : val(v) {} ;
  void show() const { cout << val << endl; }
  V value() const { return val; }
  virtual ~hold () { }
};

// member definition
template <typename T>
template <typename U>
U beta<T>::blab(U u, T t) {
  return (n.value() + q.value()) * u / t;
}

像上面这样定义成员模板会更好一些。

《C++ Prime Plus》是一本很精辟的书,也因该是C++程序员必备的书。以上例子来自于本书,转载请注明出处。

作者: YanWen

Web 开发者

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google photo

You are commenting using your Google account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s