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不需要.

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