C++新特性-auto关键字

1 auto关键字

在介绍之前,我们先来了解一个新增的关键字auto。

在C++11中,如果编译器能够在变量的声明时,能够推断出其类型;那么,代替之前必须把变量类型放在声明之前的做法,可以直接用auto进行变量的声明:

int x = 4;

也就是说,上面的声明语句可以被下面的语句替代:

auto x = 4;

当然了,这肯定不是auto关键字设计的根本目的。它最大的作用还是和模板及容器配合使用:

vector<int> vec;
auto itr = vec.iterator();
// 代替vector<int>::iterator itr

在其它的地方,auto也能购派上用场。例如,下面这个例子:

template <typename BuiltType, typename Builder>
void makeAndProcessObject (const Builder& builder)
{
    BuiltType val = builder.makeObject();
    // do stuff with val
}

这段代码中,有两个必须的模板参数,一个作为对象“builder“的类型;另一个作为对象被构建的类型。更糟糕的是,构建对象的类型不能被模板参数推导出。每一个调用都必须像:

MyObjBuilder builder;
makeAndProcessObject<MyObj>( builder );

但是,auto能够减少这种丑陋,因为你不需要在构建对象的时候,写上指定的类型。而这一切,C++替你完成,就像下面这样:

template <typename Builder>
void makeAndProcessObject (const Builder& builder)
{
    auto val = builder.makeObject();
    // do stuff with val
}

现在,你只需要一个简单的模板参数,当调用这个函数的时候,另一个参数可以非常简单地被推测出:

MyObjBuilder builder;
makeAndProcessObject( builder );

对于调用者来说,这是更好地方法,模板代码在可读性方面也没有损失什么,如果有的话,反而更容易理解了。

2 decltype和新return语法的乐趣

好了,到这里,你可能会问,是很强大,但是我想返回builder对象创建的值怎么办?标准委员会的专家们当然也想到了这个问题,他们提供了巧妙的解决方法:类型获取函数decltype()和新的return语法。

int multiply (int x, int y);

C++11的做法:返回值放到函数声明的最后,且替换返回值类型为auto关键字,就像下面这样:

auto multiply (int x, int y) -> int;

So would you want to do this? Let’s look at a simple example where it helps us: a class with an enum declared inside it:

class Person
{
public:
    enum PersonType { ADULT, CHILD, SENIOR };
    void setPersonType (PersonType person_type);
    PersonType getPersonType ();
private:
    PersonType _person_type;
};

这儿,我们有一个简单的类,Person;用enum类型数据表示其类型。但是当你定义这个类的方法的时候会发生什么呢?

第一个类方法,没有什么问题,你可以用PersonType枚举型:

void Person::setPersonType (PersonType person_type)
{
    _person_type = person_type;
}

第二个方法就有些混乱了。这个看上去相当干净的代码无法编译:

// 编译器不知道PersonType是什么?因为其在Person类外面
PersonType Person::getPersonType ()
{
    return _person_type;
}

要想编译通过,你必须这样写:

Person::PersonType Person::getPersonType ()
{
    return _person_type;
}

上面的代码使能够正常工作的。但是这却非常容易导致错误,尤其是当引进模板的时候,变得更为混乱。

这时候,就需要引进新的return语法了。把返回值放到函数的最后,你不需要添加类的范围作用符了。在编译器到达返回值的时候,它已经知道函数是Person类的一部分了,所以也就知道了PersonType是什么类型了。

auto Person::getPersonType () -> PersonType
{
    return _person_type;
}

好了,尽管很漂亮,它真的能够帮我们排忧解难?在之前,我们没有新语法,遇到问题我们不一样解决了?还没结束呢!让我们再介绍一个新的概念:decltype。

3 decltype

Decltype不是auto的恶魔卵生兄弟。Auto允许我们用一个特定的类型声明一个变量;decltype让我们从一个变量或者表达式中抽取类型。什么意思呢?看下面:

int x = 3;
decltype(x) y = x; // same thing as auto y = x;

既然能够作用于表达式,那么,如下:

decltype( builder.makeObject() )

这就让我们得到了类型不是?结合新语法,我们重新实现一开始引入的模板:

template <typename Builder>
auto makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )
{
    auto val = builder.makeObject();
    // do stuff with val
    return val;
}

可惜的是,这只能和新语法一起使用。旧的return语法是无法得到builder返回类型的。

4 Auto, References, Pointers 和 Const

auto和引用&的使用:

int& foo();
auto bar = foo(); // int& or int?

C++11有一个简短的介绍:auto默认成为引用的返回值。所以,在上面的代码中,是int。但是你可以显式地添加&,强迫成为引用:

int& foo();

auto bar = foo(); // int
auto& baz = foo(); // int&

auto指针:

int* foo();
auto p_bar = foo(); // int*

你也可以显式的指明为指针,如下所示:

int* foo();
auto *p_baz = foo(); // int*

auto和const的使用,结合引用:

int& foo();
const auto& baz = foo(); // const int&

或者,与指针

int* foo();
const int* const_foo();
const auto* p_bar = foo(); // const int*
auto p_bar = const_foo(); // const int*

总的说来,它看上去和普通的C++模板类型接口规则一样,不是吗?

1.5 编译器是否支持?

本文中提到的新特性,GCC 4.4和MSVC 10都支持。当然了,在编译的时候,你是需要指定标准的,在GCC中用-std=c++0x。

如果你使用的是其它编译器,需要查看它对C++11的支持度。

时间: 2024-10-09 06:07:59

C++新特性-auto关键字的相关文章

iOS9新特性之关键字

// // ViewController.m // 01-iOS9新特性之常见关键字 // // Created by kun on 16/8/16. // Copyright © 2016年 kun. All rights reserved. // /* nullable:1,怎么使用(语法)2,什么时候使用(作用) nullable作用:可能为空 关键字目的:迎合swift,swift是个强语言,swift必须指定一个对象是否为空 关键字好处:提高代码规范,减少沟通成本 nullable 语

ES6的新特性 — 新增关键字let、const

ECMAScript 是什么? 首先,我们都知道JavaScript由三部分组成:ECMAScript,DOM,BOM: 其中的ECMAScript是Javascript的语法规范. ECMAScript定义了很多东西,如: 语法-----解析规则,关键字,语句,声明,操作等 类型-----布尔型,数字,字符串,对象等 原型和继承 内置对象,函数的标准库----------JSON, Math, 数组方法,对象方法等 浏览器兼容: 目前Google和Firefox浏览器对ES6新特性的兼容最友好

【C++11】新特性——auto的使用

转自 http://blog.csdn.net/huang_xw/article/details/8760403 C++11中引入的auto主要有两种用途:自动类型推断和返回值占位.auto在C++98中的标识临时变量的语义,由于使用极少且多余,在C++11中已被删除.前后两个标准的auto,完全是两个概念. 1. 自动类型推断 auto自动类型推断,用于从初始化表达式中推断出变量的数据类型.通过auto的自动类型推断,可以大大简化我们的编程工作.下面是一些使用auto的例子. [cpp] vi

ios开发ios9新特性关键字学习:泛型,逆变,协变,__kindof

一:如何去学习?都去学习什么? 1:学习优秀项目的设计思想,多问几个为什么,为什么要这么设计,这么设计的好处是什么,还能不能在优化 ,如何应用到自己的项目中 2:学习优秀项目的代码风格,代码的封装设计思想,为什么要这么设计,这么设计的好处是什么,还能不能在优化 ,如何应用到自己的项目中,每行代码都要用心去写,每一行代码都要力求使最简洁的 3:学习别人遇到问题是如何分析问题,解决问题的方法是什么 4:遇到新东西应该如何去学习:1:先研究要学习的东西作用是什么 ,有什么好处  2:如何使用:具体的语

【C++11】新特性——Lambda函数

本篇文章由:http://www.sollyu.com/c11-new-lambda-function/ 文章列表 本文章为系列文章 [C++11]新特性--auto的使用 http://www.sollyu.com/c11-new-features-auto/ [C++11]新特性--Lambda函数 http://www.sollyu.com/c11-new-lambda-function/ 说明 在标准 C++,特别是当使用 C++ 标准程序库算法函数诸如 sort 和 find,用户经常

c++11 新特性之 auto关键字

C++11是对目前C++语言的扩展和修正.C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto.decltype,和模板的大量改进. g++编译c++11命令加上 -std=c++11 C++11中引入auto第一种作用是为了自动类型推导 auto的自动类型推导,用于从初始化表达式中推断出变量的数据类型.通过auto的自动类型推导,可以简化我们的编程工作 auto实际上实在编译时对变量进行了类型推导,所以不会对程序的运行效率造成不良影响另外,似乎auto并不会影响编译速度,

C++11 新特性之 decltype关键字

decltype关键字用于查询表达式的类型.与其他特性结合起来之后会有意想不到的效果. decltype的语法是 decltype (expression) 实例: #include <iostream> #include <typeinfo> using namespace std; int main() { int i; double d; float f; struct A { int i; double d; }; decltype(i) i1; cout <<

C++ 11新特性的用法之auto

一.静态类型,动态类型和类型推导 在编程语言分类中,C/C++C常常被认为是静态类型的语言.而有的编程语言则号称是"动态类型"的,比如python.通常情况下,"静"和"动"的区别是非常直观的.我们看看下面这段简单的python代码: name='world\n' print 'hello, ' %name 这段代码中python中的一个hellowworld的实现.这就是编程语言中的"动态类型",在运行时来进行类型检查,而C

WWDC2016 Session笔记 – Xcode 8 Auto Layout新特性

来源:一缕殇流化隐半边冰霜(@halfrost) 链接:http://t.cn/Rt7sKBv 目录 1.Incrementally Adopting Auto Layout 2.Design and Runtime Constraints 3.NSGridView 4.Layout Feedback Loop Debugging 一.Incrementally Adopting Auto Layout Incrementally Adopting Auto Layout是什么意思呢?在我们IB