YouTube视频链接
C++的auto关键字
本文是ChernoP56视频的学习笔记。
auto可以让C++自动推导出数据的类型,不管是在创建还是初始化变量数据时,或是将一个变量对另一个变量进行赋值。
如下代码
#includeint main(){ //auto a=5; //auto a=5.5;int a = 5;auto b = a;std::cin.get();}
在VS中将鼠标悬停在b上,可以看到int b,因为它自动推断出来了。
若有了auto还需要写类型吗?可否到处都使用auto?如下代码,name会被自动推导为std::string ,因为GetName返回的是string。
#include#includestd::string GetName(){return "Cherno";}int main(){//std::string name = GetName();auto name = GetName();std::cin.get();}
若改变这个类型为char*,我们也不需要2次改变代码。
#include#includechar* GetName(){return "Cherno";}int main(){auto name = GetName();std::cin.get();}
若不使用auto而是std::string,实际上需要改变这个函数的返回类型为std::string,我们返回的是char*,然后将其赋值非std::string,从技术上讲是可以的。因为这里有一个string类的隐式构造函数,参数可取为char*。
#include#includechar* GetName(){return "Cherno";}int main(){std::string name = GetName();std::cin.get();}
但事情还是改变了,若我们调用name.size()或类似的东西,若使用auto是不行的。
而改回std::string就可以了。
在这里auto具有两面性,一方面改变GetName函数的返回值类型,客户端不需要做任何的改动。另一方面它可能会破坏依赖于特定类型的代码。或者修改代码完美运行。因为它实际上会将其转换成std::string。
#include#include char* GetName(){return "Cherno";}int main(){std::string name = GetName();int a = name.size();std::cin.get();}
如下代码,用迭代器打印vector中的所有元素。
#include#include#include char* GetName(){return "Cherno";}int main(){std::vectorstrings;strings.push_back("Apple");strings.push_back("Orange");for (std::vector::iterator it = strings.begin();it != strings.end();it++){std::cout << *it << std::endl;}std::cin.get();}
std::vectorstd::string::iterator是一个巨大的类型,我们可以写成auto让代码更具可读性。
若有DeviceManager和Device类,我们有一个从string到vectormap(映射),变量名叫m_Devices。
#include#include#include#include char* GetName(){return "Cherno";} class Device{}; class DeviceManager { private: std::unordered_map>m_Devices; public: const std::unordered_map>& GetDevices()const { return m_Devices; } };int main(){std::vectorstrings;strings.push_back("Apple");strings.push_back("Orange");for (auto it = strings.begin();it != strings.end();it++){std::cout << *it << std::endl;}DeviceManager dm;const std::unordered_map>& //类型devices=dm.GetDevices();std::cin.get();}
我们可以用typedef或者using取个别名。
int main(){std::vectorstrings;strings.push_back("Apple");strings.push_back("Orange");for (auto it = strings.begin();it != strings.end();it++){std::cout << *it << std::endl;} using DeviceMap = std::unordered_map>;DeviceManager dm;const DeviceMap& devices=dm.GetDevices();std::cin.get();}
int main(){std::vectorstrings;strings.push_back("Apple");strings.push_back("Orange");for (auto it = strings.begin();it != strings.end();it++){std::cout << *it << std::endl;}typedef std::unordered_map> DeviceMap;DeviceManager dm;const DeviceMap& devices=dm.GetDevices();std::cin.get();}
这里是使用auto的好场景。
int main(){std::vectorstrings;strings.push_back("Apple");strings.push_back("Orange");for (auto it = strings.begin();it != strings.end();it++){std::cout << *it << std::endl;}DeviceManager dm;const auto& devices=dm.GetDevices();std::cin.get();}
若去掉const和&,将会制造一次复制操作。
DeviceManager dm; auto devices=dm.GetDevices();
像下面的代码一样,没有引用符号。
DeviceManager dm;const std::unordered_map> devices=dm.GetDevices();