C++需要了解auto的推导规则才能对auto进行正确的使用!!!
以下是对auto规则的一些总结:
1、auto声明多个变量从左向右推导,并且从右向左推导具有相同结果
2、auto声明优先拷贝,auto&&优先采用引用并且保留cv操作符限定符
(ps:int&&,char&&是右值引用)
3、auto&只能进行左值引用
4、 直接使用列表初始化,列表中必须为单元素x = {1}
用等号加列表初始化,列表中可以包含单个或者多个元素,auto类型被推导为 std::initializer_list<T>
5、auto能推断出int *等指针类型
注:auto*只能推断指针变量,否则失败
以下是一些应用
#include <iostream>
void f(auto j){ //函数是可以推断出auto类型的,编译成功
std::cout<<sizeof(j)<<'\n';
return ;
}
class Base {
public:
virtual void f()
{
std::cout << "Base::f()" << std::endl;
};
};
class Derived : public Base {
public:
virtual void f() override //overide用于告诉编译器这里重写了父类的函数,编译器回去检查重写的参数是否正确,并且会自动屏蔽父类的函数
{
std::cout << "Derived::f()" << std::endl;
};
};
int
main(){
//auto i;------此处编译器无法推断i的类型,编译失败
#if 0
long long j = 10;
auto *i = &j, m = 10ll; //1、当auto一次声明多个变量时,从左向右推导;
//2、必须保持类型的一致性————这意味着从右向左也是一样的推导结果
auto l = 1?((char)'a'):(short)9; //当我们想通过条件语句推导auto变量,编译器会选择表达能力更强的;
// short < int(long) = char(will be translated to int) < long long < double
std::cout<<l<<std::endl;
std::cout<<sizeof('a')<<std::endl;
f(1l);
f(1ll);
f(m);
f(l);
#elif 0
int o = 1;
auto oo=o; //推导类型是int,而非int&,为其开辟新的内存
auto &ooo = o;//推导类型是 int&
//auto &oooo= 1;-----采用auto&只能对左值进行引用
std::cout<<(&oo==&o)<<std::endl;
std::cout<<(&ooo==&o)<<std::endl;
#elif 0
int k = 0;
auto && lk = k; //万能引用&&将会对左值采用引用
auto && _k = 1; //万能引用&&对右值则是创建新的内存空间存储
std::cout<<(&k==&lk)<<std::endl;
#elif 0
auto x1 = { 1, 2 }; // x1类型为 std::initializer_list<int>
//auto x2 = { 1, 2.0 }; // 编译失败,花括号中元素类型不同
//auto x3{ 1, 2 }; // 编译失败,不是单个元素
auto x4 = { 3 }; // x4类型为std::initializer_list<int>
auto x5{ 3 }; // x5类型为int
#elif 1
Base* t = new Derived();
t->f();
auto b = t;
b->f();
#endif
return 0;
}
/*
总结:
1、auto声明多个变量从左向右推导,并且从右向左推导具有相同结果
2、auto声明优先拷贝,auto&&优先采用引用
3、auto&是采用推导的结果是引用;
*/