细读《Effective C++》之十二

Chapter 7. Templates and Generic Programming

Item 43 - 44

条款43:Know how to access names in templatized base classes

下面的code是无法通过编译的:

template<typename Company>
class LoggingMsgSender: public MsgSender<Company>  {
public
:
  ...                                    
// ctors, dtor, etc.

  void sendClearMsg(const MsgInfo&  info)
  {
    
// write "before sending" info to the log;

    sendClear(info);                     //  call base class function; this code will not compile!
    
// write "after sending" info to the log;

  }
  ...
};

因为存在所谓的total template specialization的情况:

template<>                                 // a total specialization of
class MsgSender<CompanyZ> {                // MsgSender; the same as the
public:                                    // general template, except
  ...                                      // sendClear is omitted
  void sendSecret(const MsgInfo&  info)
  { ... }
};

解决方案:

// 1) this->
  void sendClearMsg(const MsgInfo&  info)
  {
    
// write "before sending" info to the log;

    this->sendClear(info);                //  okay, assumes that sendClear will be inherited
    
// write "after sending" info to the log;

  }

// 2) using declaration

template<typename Company>
class LoggingMsgSender: public MsgSender<Company>  {
public
:
  
using MsgSender<Company>::sendClear;   // tell compilers to assume

  ...                                    // that sendClear is in the base class
  void sendClearMsg(const MsgInfo&  info)
  {
    ...
    sendClear(info);                   
// okay, assumes that

    ...                                // sendClear will be inherited
  }
  ...
};

// 3) explicitly specify: 破坏“virtual binding”

  void sendClearMsg(const MsgInfo&  info)
  {
    ...
    MsgSender
<Company>::sendClear(info);      // okay, assumes that

    ...                                       // sendClear will be
  }                                           //inherited

上述三种方式不过是将早期诊断延迟至晚期(具现化时),如果在base class中未能将sendClear实现,编译仍将出错。

Things to Remember

In derived class templates, refer to names in base class templates via a "this->" prefix, via using declarations, or via an explicit base class qualification.

条款44:Factor parameter-independent code out of templates

我们使用template很大程度上是因为它可以节省时间和避免重复,然而,template也可能会导致code bloat:

template<typename T,           // template for n x n matrices of
         std::size_t n>        // objects of type T; see below for info
class SquareMatrix {           // on the size_t parameter
public :
  ...
  
void invert();              // invert the matrix in place

};

SquareMatrix
<double5>
 sm1;
...
sm1.invert();                  
// call SquareMatrix<double, 5>::invert


SquareMatrix
<double10>  sm2;
...
sm2.invert();                  
// call SquareMatrix<double, 10>::invert

如果将non-type parameter抽离,可能变成这样:

template<typename T>                   // size-independent base class for
class SquareMatrixBase {               // square matrices
protected :
  ...
  
void invert(std::size_t matrixSize); // invert matrix of the given size

  ...
};

template
<typename T, std::size_t n>

class SquareMatrix: private SquareMatrixBase<T>  {
private
:
  
using SquareMatrixBase<T>::invert;   // avoid hiding base version of invert; see Item 33

public :
  ...
  
void invert() { this->invert(n); }   // make inline call to base class

};                                     // version of invert; see below for why "this->" is here

Things to Remember

1) Templates generate multiple classes and multiple functions, so any template code not dependent on a template parameter causes bloat.

2) Bloat due to non-type template parameters can often be eliminated by replacing template parameters with function parameters or class data members.

3) Bloat due to type parameters can be reduced by sharing implementations for instantiation types with identical binary representations.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值