百科问答小站 logo
百科问答小站 font logo



如何评价 C++ 11 auto 关键字? 第1页

  

user avatar   lan-se-52-30 网友的相关建议: 
      

auto很好,即使可能有些缺点,也是瑕不掩瑜。

对于auto而言,其在于type deduce,那么第一点,它不会允许没有初始化值的声明,如:

       int x;  auto y; // error      

这是很好的,有些开发者总是会直接用一些没有初始化的变量,然后后面运行结果不对。而运行的错误找起来总是比编译的难许多。

auto可以节省很多字,尤其是容器的iterator,这也是经常举的例子

       vector<int> v;  vector<int>::iterator iter = v.begin(); // #1  auto I = v.begin(); // #2       

你是喜欢 #1 还是 #2这样的写法呢?

auto配合lambda使用很好。对于lambda来说,其是一个callable object,每一个类型都是独一无二的,这个类型只有编译器知道,于是你可以:

       auto closure = [](const int&, const int&) {}      

当然,你也可以使用std::function来存储,然而这远远没有auto来的优雅。

与此同时,在C++14中,泛型lambda也允许了参数类型可以为auto类型,如

       auto closure = [](auto x, auto y) { return x * y;}     

auto配合decltype,可以解决一些以前可能需要很丑的解法

       template<class T, class U> ? ? ? mul(T x, U y)  {      return x*y;  }      

由于x, y是在参数,返回的是 x * y的类型,于是,要得到x * y的类型怎么办?当然可以利用decltype来取,但是你需要取的是 x * y的,而x,y却在参数后面,于是那就转为万能的0,在转为指针,再取指针。

       template<class T, class U> decltype(*(T*)(0)  *  *(U*)(0)) mul(T x, U y)  {      return x*y; }      

那么用auto占位置即可:

       template<class T, class U> auto mul(T x, U y) -> decltype(x * y)  {      return x*y; }      


Thanks to C++14, auto在C++14可以作为函数返回类型了,于是你可以直接这样了

       template<class T, class U> auto mul(T x, U y) {      return x*y; }      

说完这么多好处,那么来说说auto可能引起的问题。

其中第一条可能就是很多人所说的可能会降低代码的可读性。然而对于这一条,我持中立态度。若有IDE,我认为这不会是问题,但是若你认为使用强制的类型声明可以让代码更可读,也可以继续使用,C++的哲学也是相信程序员,不会束缚你做什么任何事情。

然后第二条就是auto可能得不到你预想的类型,如vector<bool>[]的返回类型。

       #include <iostream> #include <vector> #include <typeinfo> using namespace std; int main() {     vector<bool> v;     v.push_back(true);     auto var = v[0];     cout << typeid(var).name() << endl; }      

vector<bool>是一个奇葩的存在,它的[]返回的不是bool,是一个表示单独bool引用的proxy class,于是你得到是这个引用(而你平常使用bool没事,是因为完成了一个隐式转换),而你用auto的话,想要得到意想中的类型,需要使用static_cast<bool>,再给auto。而这也不是特例,其适用于含有proxy class的class。

3. auto配合decltype,有时候会让人有意想不到的结果。让我引用标准的一个例子

       int i; int&& f(); auto x3a = i; // decltype(x3a) is int decltype(auto) x3d = i; // decltype(x3d) is int auto x4a = (i); // decltype(x4a) is int decltype(auto) x4d = (i); // decltype(x4d) is int& auto x5a = f(); // decltype(x5a) is int decltype(auto) x5d = f(); // decltype(x5d) is int&& auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int> decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression auto *x7a = &i; // decltype(x7a) is int* decltype(auto)*x7d = &i; // error, declared type is not plain decltype(auto)      



  

相关话题

  Java为什么选择interface来作为"接口"这个功能的关键字? 
  有没有什么上古的程序代码至今依然没被更替? 
  当下软件开发语言腾出不穷,作为老牌c++GUI领域top1的QT未来会怎样? 
  在大型项目上,Python 是个烂语言吗? 
  程序员最理想的工作环境应该是什么样的? 
  ios编程是吃青春饭吗? 
  批判易语言的人是否用过这门语言,批判它的原因又是什么? 
  怎样评价《数码宝贝》第一部中的泉光子郎的编程水平? 
  法国亿万富翁筹资一亿美元在硅谷建立「免学费」大学启动「42」计划的目的是什么? 
  0除以0怎么使用c++的异常处理,例如try? 

前一个讨论
为什么 Go 语言在某些方面的性能还不如 Java?
下一个讨论
为什么说温室里长不出参天大树?





© 2024-06-26 - tinynew.org. All Rights Reserved.
© 2024-06-26 - tinynew.org. 保留所有权利