条款9.优先选用别名声明,而非typedef

优先选择别名声明,而非typedef

typedef用法:

typedef 
std::unique_ptr<std::unordered_map<std::string, std::string>> UPtrMapSS;

using用法(别名声明):

using UPtrMapSS = std::unique_ptr<std::unordered_map<std::string, std::string>>;

别名声明可以模板化(这种情况下,它们被称为别名模板),typedef就不行

比如,想要定义一个同义词,表达一个链表,它使用了一个自定义分配器MyAlloc

template<typename T>
using MyAllocList = std::list<T,MyAlloc<T>>;

MyAllocList<Widget> lw;

如果使用typedef的话

template<typename T>
struct MyAllocList{
	typedef std::list<T, MyAlloc<T>> type; 
};

MyAllocList<Widget>::type lw;

如果想在模板内使用typedef来创建一个表,它容纳的对象类型由模板形参指定的话,那你就要给typedef前缀。

template<typename T>
class Widget{
private:
    typename MyAllocList<T>::type list;
};

这里,MyAllocList<T>::type代表一个依赖于模板类型形参T的类型,所以MyAllocList<T>::type称为带依赖类型,而c++中的规则就是带依赖类型前面必须加个typename

如果MyAllocList是使用别名模板来定义的,那么要写typename的要求就消失了。

template<typename T>
using MyAllocList = std::list<T, MyAlloc<T>>;

template<typename T>
class Widget{
private:
    MyAllocList<T> list;
};

当编译器处理到Widget模板并遇到了MyAllocList<T>时,它们知道MyAllocList<T>是一个类型的名字,因为MyAllocList<T>是个非依赖性类型,所以typename饰词既不要求也不允许。

当编译器遇到了Widget模板中的MyAllocList<T>::type时,它们不可能确定MyAllocList<T>::type命名了一个类型,因为可能在MyAllocList的某个特化中,MyAllocList<T>::type表示并非类型而是其他的什么东西。

class Wine{};

template<>
class MyAllocList<Wine>
{
	enum class WineType{ White,Red,Rose };
    WineType type;		//在这个类中,type是个数据成员
    ...
};

如果Widget模板采用Wine类型进行实现,则其中的MyAllocList<T>::type就表示一个数据成员而非类型。

编译器要求在前面加一个typename,是为了判断Widget模板中的MyAllocList<T>::type究竟是否表示一个类型。

c++11以类型特征的形式给程序员以执行此变换的工具。

类型特征是在头文件<type_traits>给出的一整套模板。该头文件中有几十个类型特征,它们并非都是执行类型变换功能的用途,也包含了一些可于此的接口。

对给定待变换类型T,其结果类型为std::transformation<T>::type

std::remove_const<T>::type	//由const T生成T
std::remove_reference<T>::type	//由T&或T&&生成T
std::add_lvalue_reference<T>::type	//由T生成T&

如果想将它们应用与模板内的类型形参,那就还是要每次都在前面加上typename。这两个词法存在的原因是,C++11中的类型特征是用嵌套在模板化的struct里的typedef实现的。

要点速记

  • typedef不支持模板化,但是别名声明支持
  • 别名模板可以让人免写::type后缀,并且在模板中,对于内嵌typedef的引用经常要求加上typename前缀
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值