Effective Modern C++读书笔记:条款09

Aki 发布于 2023-01-09 217 次阅读


09优先选用别名声明using,而非typedef:

using别名声明和typedef声明都可以完成一个类型的声明,但使用using可以很简单且直接的完成这个操作,特别是模版操作时,下面将通过代码分别声明相同的类型,就可以看出using的好处了。

// 声明函数指针,返回值为void,参数为int,double
typedef void(*FP)(int ,double);   // typedef晦涩不直白
using FP = void(*)(int ,double);  // using简单直白


// typedef声明一个模板,表示一个链表
template<class T>
struct MyAllocList
{
  typedef std::list<T,MyAlloc<T>> type; // typedef晦涩不直白
};
 
MyAllocList::type myList;  // 类型使用晦涩不直白


// using 声明一个模板,表示一个链表
template<class T>
using MyAllocList std::list<T,MyAlloc<T>>; // using简单直白
MyAllocList myList; // 类型使用简单直白

还有一种更糟糕的情况,那就是如果这时候你想在一个模板内,使用typedef来创建一个链表,且它容纳的类型由模板参数指定,这时候你不得不在typedef的前面加上一个typename前缀,以表明该typedef是一个类型,十分麻烦复杂。但是使用using的话,完全不必要。

// typedef声明一个模板,表示一个链表
template<class T>
struct MyAllocList
{
  typedef std::list<T,MyAlloc<T>> type; // typedef晦涩不直白
};
 
template<class T>
class Widget
{
private:
    typename MyAllocList<T>::type list; // 必须加上typename,否则编译器不知道其是个类型
};
 
 
// using 声明一个模板,表示一个链表
template<class T>
using MyAllocList std::list<T,MyAlloc<T>>; // using简单直白
 
template<class T>
class Widget {
private:
    MyAllocList<T> list;    // so easy
};

请记住:

  • typedef不支持模板化,但是别名声明支持
  • 别名模板可以让人免写::type后缀,并且在模板中,对于内嵌typedef的引用经常要求加上typename前缀