总览
using
比typedef
好在哪些地方.
using
支持模板的别名.
using
有编译器加持.相同点
都是别名,不过
using
的看起来更加简洁.
相同点
别名
#include<iostream> using Myshow = void (*)(); typedef void(*Dshow)(); void show() { std::cout << __LINE__ << std::endl; } int main() { Myshow{&show}(); Dshow{&show}(); // 二义性,优先定义,而非初始化. // Dshow(&show)(); }
都挺简单,但是
typedef
的有点略难懂.
模板别名
using
#include<iostream> #include<vector> template<typename T> using Myvector = std::vector<T>; int main() { Myvector<int> b{1,2,3}; for(const auto& a : b) { std::cout << a << std::endl; } }
正常编译执行
typedef
模仿#include<iostream> #include<vector> template<typename T> typedef std::vector<T> Myvector; int main() { Myvector<int> b{1,2,3}; for(const auto& a : b) { std::cout << a << std::endl; } }
编译报错
改改
typedef
#include<iostream> #include<vector> template<typename T> struct Myvector { typedef std::vector<T> type; }; int main() { Myvector<int>::type b{1,2,3}; for(const auto& a : b) { std::cout << a << std::endl; } }
勉强可以用,但是不够简洁了呀.
别名类型做成员变量
using
#include<iostream> #include<vector> template<typename T> using Myvector = std::vector<T>; template<typename T> class Temp { public: Myvector<T> a; }; int main() { Temp<int> b{{1,2,3}}; for(const auto& a : b.a) { std::cout << a << std::endl; } }
正常输出
123
.
typedef
#include<iostream> #include<vector> template<typename T> typedef std::vector<T> Myvector; template<typename T> class Temp { public: Myvector<T> a; }; int main() { Temp<int> b{{1,2,3}}; for(const auto& a : b.a) { std::cout << a << std::endl; } }
这种肯定编不过.上面都编不过。
typedef
改改版#include<iostream> #include<vector> template<typename T> struct Myvector { typedef std::vector<T> type; }; template<typename T> class Temp { public: Myvector<T>::type a; }; int main() { Temp<int> b{{1,2,3}}; for(const auto& a : b.a) { std::cout << a << std::endl; } }
用上面的改一改,加内置了,编译报错.
因为不知道
type
是类型还是变量名.无法预测未来.可行版
typedef
#include<iostream> #include<vector> template<typename T> struct Myvector { typedef std::vector<T> type; }; template<typename T> class Temp { public: typename Myvector<T>::type a; }; int main() { Temp<int> b{{1,2,3}}; for(const auto& a : b.a) { std::cout << a << std::endl; } }
这种是可行的,但是看起来好麻烦.
必须通过关键字
typename
告诉编译器Myvector<T>::type
是一个类型而不是变量.小结
typedef
在c++11
没有办法完美的适应环境了.间接类型需要用
typename
声明其是类型不是变量名.编译器笨吧.
using
命名后的就不需要也不允许typename
的出现了.小疑问
Myvector<T>::type
如果是类型,Myvector<T>::type()
就是匿名对象创建,调用默认构造.或者是函数声明?Myvector<T>::type
如果是变量名,恰好是个可调用对象,那么就是匿名返回值. 无法解析.语义都不一样了.
为什么不增强typedef
的功能
开发就需要做到,不改原来的基础上增加新的功能. 开闭原则.
C++
标准库的实现
type_traits
主要是用在元模板编程了.
可以通过传入类型然后返回这个类型的另外的类型,比如加减修饰.
const
类型获取对应的非const
类型.&
类型获取到对应的非引用类型.获取某个类型的普通版本变量
#include <iostream> #include <type_traits> int main() { const int a = 0; std::remove_const<decltype(a)>::type b; b = 1; return 0; }
得到这个变量的普通版本.
不太好看,每次都要加一个
::type
.
using
版本#include <iostream> #include <type_traits> template <typename T> using remove_const_t = typename std::remove_const<T>::type; int main() { const int a = 0; remove_const_t<decltype(a)> b; b = 1; return 0; }
typedef
无法支持,只能在内部类中创建.
type_traits
c++11
使用的typedef
在内部实现的这种机制.
c++14
的时候才采用typedef
的方式实现.remove_const_t
的形式. 如上.
总结
using
在模板别名方面表现比typedef
好.
using
有编译器加持.间接名需要用
typename
而typedef
不需要.