Modern C++之别名声明

本文介绍了C++中类型别名的使用方法,包括C++98时代的typedef和C++11后的using关键字,并对比了两者在模板编程中的优劣。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们在编写代码的时候经常会使用类型别名,比如定义自己的内置类型(跨平台)或者为了简化某种很长的类型。在C++ 98时代我们会使用typedef来完成这个工作。

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

C++11以后增加了别名声明,它使用using关键字。

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

看上去使用using声明比typedef更容易理解。

typedef void (*FP)(int, const std::string&);
using FP = void (*)(int, const std::string&);

using比typedef的优势体现在模板编程上。

template<typename T>
using MyAllocList = std::list<T, MyAlloc<T>>;
//MyAllocList<T>是std::list<T, MyAlloc<T>>的别名

MyAllocList<Wideget> lw;

如果使用typedef则要麻烦很多。

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

MyAllocList<Widget>::type lw;

如果使用typedef来定义型别,编译器可能无法判断这个别名到底是个型别还是一个成员变量,我们需要加上typename前缀来告诉编译器,这是一个型别,比如:

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

class Wine { ... };
template<>
class MyAllocList<Wine> {
    private:
        enum class WineType
        {White, Red, Rose};
        WineType type;
}

//MyAllocList<wine>::type是一个成员变量而非型别

type是一个型别还是一个变量,编译器需要根据T的型别进行推导。但是使用using型别声明,编译器可以很明确的知道这个就是一个型别而非变量。

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

C++11的型别特征转换还是通过typedef实现的,比如:

std::remove_const<T>::type

C++14中则使用了using别名声明,因此可以使用下面的方式做转换。

std::remove_const_t<T>等价于std::remove_const<T>::type

如果你还在使用C++11完全可以自己使用using来定义这个转换以达到c++14的效果。

template<class T>
using remove_const_t = typename remove_const<T>::type;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值