细读《Effective C++》之十一

Chapter 7. Templates and Generic Programming

Scott在Item 01里面就列举出了C++中的四种所谓“sublanguages”:C、OO C++、Template C++、STL。前面的Items一直评论的是OO C++,这一章则主要针对Template C++。

Item 41 - 42

条款41:Understand implicit interfaces and compile-time polymorphism

在OO C++中,是使用explicit interface和runtime polymorphism解决polymorphism问题的,而Template C++则是通过implicit interface和compile-time polymorphism解决polymorphism问题:

// OO C++
class  Widget {
public
:
  Widget();
  
virtual ~
Widget();
  
virtual std::size_t size() const
;
  
virtual void
 normalize();
  
void swap(Widget& other);                 // see Item 25

  ...
};

void doProcessing(Widget&
 w)
{
  
if (w.size() > 10 && w !=
 someNastyWidget) {
    Widget temp(w);
    temp.normalize();
    temp.swap(w);
  }
}

// template C++

template<typename T>
void doProcessing(T&  w)
{
  
if (w.size() > 10 && w !=
 someNastyWidget) {
    T temp(w);
    temp.normalize();
    temp.swap(w);
  }
}

Implicit interfaces并不基于function signatures,从上面的valid expressions可以看出,w要支持size、normalize、swap、copy constructor、operator !=等implicit interfaces。由于operator overloading的因素,这些条件都不需要满足:size、normalize、swap可以从base class继承,copy constructor可以采用default,只要存在operator !=隐式转换类型即可满足。

Things to Remember

1) Both classes and templates support interfaces and polymorphism.

2) For classes, interfaces are explicit and centered on function signatures. Polymorphism occurs at runtime through virtual functions.

3) For template parameters, interfaces are implicit and based on valid expressions. Polymorphism occurs during compilation through template instantiation and function overloading resolution.

条款42:Understand the two meanings of typename

1、声明template type parameter:

template<class T> class Widget;                 // uses "class"
template<typename T> class Widget;              // uses "typename"

2、指涉nested dependent type name:

template<typename C>                            // this is valid C++
void print2nd(const C&  container)
{
  
if (container.size() >= 2
) {
    typename C::const_iterator iter(container.begin());
    ...
  }
}

template
<typename C>                   // typename allowed (as is "class")

void f(const C& container,             // typename not allowed
    typename C::iterator iter);        // typename required

template
<typename T>
class Derived: public Base<T>::Nested { // base class list: typename not
public:                                 // allowed
  explicit Derived(int  x)
  : Base
<T>::Nested(x)                  // base class identifier in mem

  {                                     // init. list: typename not allowed
    typename Base<T>::Nested temp;      // use of nested dependent type
    ...                                 // name not in a base class list or
  }                                     // as a base class identifier in a
  ...                                   // mem. init. list: typename required
};

Things to Remember

1) When declaring template parameters, class and typename are interchangeable.

2) Use typename to identify nested dependent type names, except in base class lists or as a base class identifier in a member initialization list. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值