C++中的关键字auto

百度百科
维基百科
C语言

  • auto被解释为一个自动存储变量的关键字,也就是申明一块临时的变量内存
auto double a=3.7;

C++ 98标准/C++03标准

  • 同C语言的意思完全一样:auto被解释为一个自动存储变量的关键字,也就是申明一块临时的变量内存。

C++ 11标准

  • 在C++11标准的语法中,auto被定义为自动推断变量的类型。
    例如:
auto x=5.2;//这里的x被auto推断为double类型

map<int,int>m;
for(auto it=m.begin();//这里it被auto推断为map<int,int>::iterator类型
it!=m.end();++it)
{
//....
}

auto的自动类型推断发生在编译期,所以使用auto并不会造成程序运行时效率的降低。是否会造成编译期的时间消耗,
auto使用注意事项:
(1)auto 变量必须在定义时初始化;
(2)定义在一个auto序列的变量必须始终推导成同一类型,如:

auto a = 1, b = 2, c = 3;     // 正确
auto a = 1, b = 2.2, c = 'c'; // 错误(这个道理和第一点注意事项相同)

(3)如果初始化表达式是引用,则去除引用语义,如:

int  a = 1;
int &b = a;


auto  c = b; // 此时c的类型被推导为 int32,而不是int32&
auto &c = b; // 此时c的类型才是int&

(4)如果初始化表达式为const或volatile(或者两者兼有),则除去const/volatile语义。

const int a = 10;
auto  b= a;         // b的类型为int而非const int(去除const)
const auto c = a;   // 此时c的类型为const int

b = 100;   // 合法
c = 100;   // 错误

(5)如果auto关键字带上&号,则不去除const语义。

const int a = 10;
auto &b = a;    // 因为auto带上&,故不去除const,b类型为const int

b = 10;   /非法

(6)初始化表达式为数组时,auto关键字推导类型为指针。

int a[3] = { 1, 2, 3 };
auto b = a;


std::cout << typeid(b).name() << std::endl;   // 这里输出 int*

(7)如果表达式为数组且auto带上&,则推导类型为数组类型。

int a[3] = { 1, 2, 3 };
auto &b = a;

std::cout << typeid(b).name() << std::endl; // 这里输出 int[3]

(8)函数或模板参数不能被声明为auto。

void func(auto a)  // 错误
{
    //... 
}

(9)auto不是一个真正的类型,仅仅是一个占位符,不能使用一些以类型为操作数的操作符,如sizeof或typeid:

std::cout << sizeof(auto) << std::endl;        // 错误
std::cout << typeid(auto).name() << std::endl; // 错误
  • 简单的变量声明类型,不建议用auto关键字,而是应更清晰地直接写出其类型。
  • auto关键字更适用于类型冗长复杂、变量使用范围专一时,使程序更清晰易读,比如下面
 std::vector<int> vect; 
 for(auto it = vect.begin(); it != vect.end(); ++it)
 {  //it的类型是std::vector<int>::iterator
    std::cin >> *it;
  }
  • 或者保存lambda表达式类型的变量声明:
auto ptr = [](double x){return x*x;};//类型为std::function<double(double)>函数对象
  • 在模板函数定义时,如果变量的类型依赖于模板参数,使用auto关键字使得在编译期确定这些类型,如:
template <class T, class U>void Multiply(T t, U u)
{
     auto v = t * u;
     std::cout<<v;
}
  • 模板函数的返回类型如果也是依赖于从模板参数推导,
 template <typename _Tx, typename _Ty>
 auto multiply(_Tx v1, _Ty v2) -> decltype( _Tx * _Ty )
 {
     return v1*v2;
 }
 auto result = multiply(101, 1.414); // 结果类型是double
  • auto关键字的类型完美转发

    C++11使用auto声明变量时,如:auto&& var=initValue;“auto&&”并不意味着这一定是右值引用类型的变量,而是类似于模板函数参数的类型推导,既可能是左值引用,也可能是右值引用。其目的是把初始化表达式的值分类情况,完美转发给由auto声明的变量。C++11的左值引用与右值引用总结 也即:
      1.如果初始化值(initializer)是类型A的左值,则声明的变量类型为左值引用A&;
      2.如果初始化值是类型A的右值,则声明的变量类型为右值引用A&&。

#include<iostream>  
#include <vector>
#include <typeinfo>
using namespace std;
 
struct Widget{};
Widget makeWidget(){ return Widget(); } // 类工厂函数

int main()
{
	Widget&& var1 = Widget(); // var1的类型是右值引用,但是作为左值
	auto&& var2 = var1;       //var2的类型是左值引用
	std::vector<int> v = { 1, 2, 3 };
	auto&& val = v[0]; // std::vector::operator[]的返回值是元素左值,所以val的类型是左值引用
	Widget&& var3 = makeWidget(); // var3是左值,但它的类型是右值引用 
	Widget var4 = static_cast<Widget&&>(var1); // var4是左值,但它的类型是右值引用

	std::cout << typeid(var1).name() << std::endl;//struct Widget
	std::cout << typeid(var2).name() << std::endl;//struct Widget
	std::cout << typeid(val).name() << std::endl;//int
	std::cout << typeid(var3).name()  << std::endl;//struct Widget
	std::cout << typeid(var4).name() << std::endl;//struct Widget
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值