- 别名声明和typedef都能避免使用冗长的变量名称,但是别名声明更加直观,如下:
cpp
typedef
std::unique_ptr<std::unordered_map<std::string, std::string>>
UPtrMapSS;
using UPtrMapSS =
std::unique_ptr<std::unordered_map<std::string, std::string>>;
typedef void (*FP)(int, const std::string&);
using FP = void (*)(int, const std::string&);
- 别名声明可以被模板化但是
typedef
不能,typedef
嵌套进模板化的struct才能等效
并且使用typedef
声明一个使用了模板形参的对象,必须在typedef
前面加上typename
cpp
// using
template<typename T>
using MyAllocList = std::list<T, MyAlloc<T>>;
MyAllocList<Widget> lw;
template<typename T>
class Widget {
private:
MyAllocList<T> list;
};
// typedef
template<typename T>
struct MyAllocList {
typedef std::list<T, MyAlloc<T>> type;
};
MyAllocList<Widget>::type lw;
template<typename T>
class Widget {
private:
typename MyAllocList<T>::type list;
};
- 使用typedef定义的
MyAllocList<T>
::type是一个依赖类型, 必须使用typename
修饰符,避免出现歧义
cpp
class Wine { ... };
template<> //当T是Wine
class MyAllocList<Wine> { //特化MyAllocList
private:
enum class WineType
{ White, Red, Rose };
WineType type; //在这个类中,type是一个数据成员!
};
说明:如果Widget
使用Wine
实例化,在Widget
模板中的MyAllocList<Wine>::type
将会是一个数据成员,不是一个类型,在Widget
模板内,MyAllocList<T>::type
是否表示一个类型取决于T
是什么,这就是为什么编译器会坚持要求你在前面加上typename