using 还是 typedef

  • 总览

    • usingtypedef好在哪些地方.

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

    • 小结

      • typedefc++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有编译器加持.

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

  • 發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章