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

本文比较了C++中using和typedef在模板别名、编译器支持及间接类型使用上的区别,强调了using的简洁优势和typedef在C++11后的局限。讨论了如何在现代C++中正确使用它们,并通过实例展示了各自的适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值