当前位置: 代码迷 >> 综合 >> c++11 推荐用 using 而不是 typedef
  详细解决方案

c++11 推荐用 using 而不是 typedef

热度:72   发布时间:2023-12-22 02:46:47.0
  1. 总览

    • usingtypedef好在哪些地方.

      • using支持模板的别名.

      • using有编译器加持.

    • 相同点

      • 都是别名,不过using的看起来更加简洁.

  2. 相同点

    • 别名

      #include<iostream>
      using Myshow = void (*)();
      typedef void(*Dshow)();
      void show() {
                std::cout << __LINE__ << std::endl;
      }int main() {
                Myshow{
                &show}();Dshow{
                &show}();// 二义性,优先定义,而非初始化.// Dshow(&show)();
      }
      
      • 都挺简单,但是typedef的有点略难懂.

  3. 模板别名

    • 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;}
      }
      
      • 勉强可以用,但是不够简洁了呀.

  4. 别名类型做成员变量

    • 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是一个类型而不是变量.

    • 小结

      • typedefc++11没有办法完美的适应环境了.

      • 间接类型需要用typename声明其是类型不是变量名.编译器笨吧.

      • using命名后的就不需要也不允许typename的出现了.

    • 小疑问

      • Myvector<T>::type如果是类型,Myvector<T>::type()就是匿名对象创建,调用默认构造.或者是函数声明?
      • Myvector<T>::type如果是变量名,恰好是个可调用对象,那么就是匿名返回值. 无法解析.语义都不一样了.
  5. 为什么不增强typedef的功能

    • 开发就需要做到,不改原来的基础上增加新的功能. 开闭原则.

  6. 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的形式. 如上.

  7. 总结

    • using在模板别名方面表现比typedef好.

    • using有编译器加持.

    • 间接名需要用typenametypedef不需要.