码迷,mamicode.com
首页 > 编程语言 > 详细

C++新特性-auto关键字

时间:2017-02-24 14:28:38      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:ide   comment   语法   private   第一个   number   ext   pretty   特性   

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的支持度。

C++新特性-auto关键字

标签:ide   comment   语法   private   第一个   number   ext   pretty   特性   

原文地址:http://blog.csdn.net/shenwanjiang111/article/details/56334243

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!