auto的优势

  1. 总览

    • 主旨

      • 大多数都推荐用auto,少数情况还是要用显式声明.
    • 主要内容

      • 养成声明并初始化的习惯.
      • auto的代码更简洁.
      • auto可以声明未知类型变量.
      • autostd::function的好处.
  2. 必须赋值

    • 说明

      • 变量声明的时候就给赋值,可以一定程度上避免错误.
      • 声明并赋值效率可能并不高,不过代码更严谨.所以一般推崇使用的地方声明并定义.
    • 效果

      • 不初始化编译不通过,编译阶段的检查.
    • 案例一

      int main() {
                
                
         auto a;
         return 0;
      }
      
      • 编译不通过,auto必须赋值。养成定义并赋值的好习惯。
  3. 复杂变量类型简单化

    • 说明

      • 复杂的内置变量类型声明很长一串,还不一定对.用auto比较合适.
    • 案例一

      #include<vector>
      template <typename Iter>
      void foreach(Iter b, Iter e) {
                
                
         while (b != e) {
                
                
             std::iterator_traits<Iter>::value_type value = *b;
             b++;
         }
      }
      int main() {
                
                
         char s[10];
         foreach(s, s + 10);
         return 0;
      }
      
      • 编译报错,一大串的从属类型,必须用typename关键字声明后面的是类型而不是变量名才可以.
    • 案例二

      #include<vector>
      template <typename Iter>
      void foreach(Iter b, Iter e) {
                
                
         while (b != e) {
                
                
             typename std::iterator_traits<Iter>::value_type value = *b;
             b++;
         }
      }
      int main() {
                
                
         char s[10];
         foreach(s, s + 10);
         return 0;
      }
      
      • 一大长传,还不一定对。可能还会涉及到拷贝.
    • 案例三

      #include<vector>
      template <typename Iter>
      void foreach(Iter b, Iter e) {
                
                
         while (b != e) {
                
                
             auto value = *b;
             b++;
         }
      }
      int main() {
                
                
         char s[10];
         foreach(s, s + 10);
         return 0;
      }
      
      • 没有复杂的类型声明,很简单的解决了问题。
  4. lambda

    • 说明

      • lambda是一个局部类型,类型和变量名和所在环境相关.
      • 命名也不一样,可以通过反汇编或者objdump -d查看对应符号名.
    • 案例一

      int main() {
                
                
         auto s = []() {
                
                };
         decltype(s) t = s;
         return 0;
      }
      
      • 成功,类型推导赋值。
    • 案例二

      int main() {
                
                
         auto s = []() {
                
                };
         s = []() {
                
                };
         return 0;
      }
      
      • 编译错误,类型不匹配.
      template<typename T>
      void show(T&& t) {
                
                
         t.error();
      }
      int main() {
                
                
         auto s = []() {
                
                };
         auto p = []() {
                
                };
         show(s);
         show(p);
         return 0;
      }
      
      • 编译的结果是,两个类型不一样,是一个hash值.
    • 案例三

      int main() {
                
                
         auto s = [](int a,int b) {
                
                };
         return 0;
      }
      
      • C++11的简单版本。
      int main() {
                
                
         auto s = [](auto a,auto b) {
                
                };
         return 0;
      }
      
      • C++14的更简单版本,特别是在函数特别复杂的时候.
  5. autostd::function更优

    • 说明

      • 有时候一个变量用std::function存储,可能会因为存不下而分配额外的内存来存储,内存分配就可能失败.
      • 而且执行效率低.
    • 案例一

      #include<functional>
      int main() {
                
                
         std::function<void(int,int)> c = [](int a, int b) {
                
                };
         c = [](int a, int b) {
                
                };
         return 0;
      }
      
      • 编译成功。前面的两个lambda会失败,因为是随机类型,但是这里不会.
      • 但是这里同样会声明类型,而且很可能也是一大串。在简洁和执行效率上就比不上auto.
  6. 溢出

    • 说明

      • 自己定义的类型并不是返回的类型.
      • 不同平台就可能出错.
    • 案例一

      #include<vector>
      int main() {
                
                
         std::vector<int> s{
                
                 1,2,3,4,5 };
         int t = s.size();
         return 0;
      }
      
      • 32编译成功,但是在64就可能不会成功,会编译警告.
      • 这是因为64使用的是long并不是int.
      • 就会导致溢出问题.
  7. 隐式转换

    • 主要是类型不一致,导致了隐式转换生成了拷贝版本.效率低。

  8. 总结

    • 推荐用,方便,节约内存.

    • 推荐不是强制,有的地方也建议用直接声明.

猜你喜欢

转载自blog.csdn.net/rubikchen/article/details/121667624