C++11新特性:自动类型推断和类型获取

声明:本文是在Alex Allain的文章http://www.cprogramming.com/c++11/c++11-auto-decltype-return-value-after-function.html的基础上写成的。

加入了很多个人的理解,不是翻译。

转载请注明出处 http://blog.csdn.net/srzhz/article/details/7934483

自动类型推断

当编译器能够在一个变量的声明时候就推断出它的类型,那么你就能够用auto关键字来作为他们的类型:

[cpp] view plaincopy

  1. auto x = 1;

编译器当然知道x是integer类型的。所以你就不用int了。接触过泛型编程或者API编程的人大概可以猜出自动类型推断是做什么用的了:帮你省去大量冗长的类型声明语句。

比如下面这个例子:

在原来的C++中,你要想使用vector的迭代器得这么写:

[cpp] view plaincopy

  1. vector<int> vec;
  2. vector<int>::iterator itr = vec.iterator();

看起来就很不爽。现在你可以这么写了:

[cpp] view plaincopy

  1. vector<int> vec;
  2. auto itr = vec.iterator();

果断简洁多了吧。假如说自动类型推断只有这样的用法的话那未免也太naive了。在很多情况下它还能提供更深层次的便利。

比如说有这样的代码:

[cpp] view plaincopy

  1. template <typename BuiltType, typename Builder>
  2. void
  3. makeAndProcessObject (const Builder& builder)
  4. {
  5. BuiltType val = builder.makeObject();
  6. // do stuff with val
  7. }

这个函数的功能是要使用builder的makeObject产生的实例来进行某些操作。但是现在引入了泛型编程。builder的类型不同,那么makeObject返回的类型也不同,那么我们这里就得引入两个泛型。看起来很复杂是吧,所以这里就可以使用自动类型推断来简化操作:

[cpp] view plaincopy

  1. template <typename Builder>
  2. void
  3. makeAndProcessObject (const Builder& builder)
  4. {
  5. auto val = builder.makeObject();
  6. // do stuff with val
  7. }

因为在得之builder的类型之后,编译器就已经能知道makeObject的返回值类型了。所以我们能够让编译器自动去推断val的类型。这样一来就省去了一个泛型。

你以为自动类型推断只有这样的用法?那也太naive了。C++11还允许对函数的返回值进行类型推断

新的返回值语法和类型获取(Decltype)语句

在原来,我们声明一个函数都是这样的:

[cpp] view plaincopy

  1. int temp(int a, double b);

前面那个int是函数的返回值类型,temp是函数名,int a, double b是参数列表。

现在你可以将函数返回值类型移到到参数列表之后来定义:

[cpp] view plaincopy

  1. auto temp(int a, double b) -> int;

后置返回值类型可以有很多用处。比如有下列的类定义:

[cpp] view plaincopy

  1. class Person
  2. {
  3. public:
  4. enum PersonType { ADULT, CHILD, SENIOR };
  5. void setPersonType (PersonType person_type);
  6. PersonType getPersonType ();
  7. private:
  8. PersonType _person_type;
  9. };

那么在定义getPersonType函数的时候我们得这么写:

[cpp] view plaincopy

  1. Person::PersonType Person::getPersonType ()
  2. {
  3. return _person_type;
  4. }

因为函数所在的类Person是声明在函数返回值之后的,所以在写返回值的时候编译器并不知道这个函数是在哪个类里面。由于PersonTYpe是Person类的内部声明的枚举,所以在看到PersonType的时候,编译器是找不到这个类型的。所以你就得在PersonTYpe前面加上Person::,告诉编译器这个类型是属于Person的。这看起来有点麻烦是吧。当你使用新的返回值语法的时候呢就可以这么写:

[cpp] view plaincopy

  1. auto Person::getPersonType () -> PersonType
  2. {
  3. return _person_type;
  4. }

因为这次编译器看到返回值类型PersonType的时候已经知道这个函数属于类Person。所以它会到Person类中去找到这个枚举类型。

当然上述应用只能说是一个奇技淫巧而已。并没有帮我们多大的忙(代码甚至都没有变短)。所以还得引入C++11的另一个功能。

类型获取(Decltype)

既然编译器能够推断一个变量的类型,那么我们在代码中就应该能显示地获得一个变量的类型信息。所以C++介绍了另一个功能:decltype。(实在是不知道这个词该怎么翻译,姑且称之为类型获取)。

[cpp] view plaincopy

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

上述代码就使用了类型获取功能。和函数返回值后置语法结合起来,可以有如下应用:

[cpp] view plaincopy

  1. template <typename Builder>
  2. auto
  3. makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )
  4. {
  5. auto val = builder.makeObject();
  6. // do stuff with val
  7. return val;
  8. }

前面的例子中这个函数的返回值是void,所以不需要为返回值引入泛型。如果返回值是makeObject的返回值的话,那么这个函数就得引入两个泛型。现在又了类型获取功能,我们就能在返回值中自动推断makeObject的类型了。所以decltype确实为我们提供了很大的便利。

这个功能非常重要,在很多时候,尤其是引入了泛型编程的时候,你可能记不住一个变量的类型或者类型太过复杂以至于写不出来。你就要灵活使用decltype来获取这个变量的类型。

自动类型推断在Lambda表达式(匿名函数)中的作用

请参考http://blog.csdn.net/srzhz/article/details/7934652

C++11新特性:自动类型推断和类型获取,布布扣,bubuko.com

时间: 2024-08-04 03:49:51

C++11新特性:自动类型推断和类型获取的相关文章

【C++11】30分钟了解C++11新特性

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 什么是C++11 C++11是曾经被叫做C++0x,是对目前C++语言的扩展和修正,C++11不仅包含核心语言的新机能,而且扩展了C++的标准程序库(STL),并入了大部分的C++ Technical Report 1(TR1)程序库(数学的特殊函数除外). C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto.decl

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新特性:Lambda函数(匿名函数)

声明:本文参考了Alex Allain的文章http://www.cprogramming.com/c++11/c++11-lambda-closures.html 加入了自己的理解,不是简单的翻译 C++11终于知道要在语言中加入匿名函数了.匿名函数在很多时候可以为编码提供便利,这在下文会提到.很多语言中的匿名函数,如C++,都是用Lambda表达式实现的.Lambda表达式又称为lambda函数.我在下文中称之为Lambda函数. 为了明白Lambda函数的用处,请务必先搞明白C++中的自动

Cocos2d-x 3.1.1 学习日志6--30分钟了解C++11新特性

新的关键字 auto C++11中引入auto第一种作用是为了自动类型推导 auto的自动类型推导,用于从初始化表达式中推断出变量的数据类型.通过auto的自动类型推导,可以大大简化我们的编程工作.auto实际上实在编译时对变量进行了类型推导,所以不会对程序的运行效率造成不良影响.另外,似乎auto并不会影响编译速度,因为编译时本来也要右侧推导然后判断与左侧是否匹配.如果没有auto关键字 写个迭代器要写很长长,这也算是节省了我们的脑细胞吧,~~~~(>_<)~~~~ !! auto a; /

[转]30分钟了解C++11新特性

新的关键字 autoC++11中引入auto第一种作用是为了自动类型推导auto的自动类型推导,用于从初始化表达式中推断出变量的数据类型.通过auto的自动类型推导,可以大大简化我们的编程工作.auto实际上实在编译时对变量进行了类型推导,所以不会对程序的运行效率造成不良影响.另外,似乎auto并不会影响编译速度,因为编译时本来也要右侧推导然后判断与左侧是否匹配.如果没有auto关键字 写个迭代器要写很长长,这也算是节省了我们的脑细胞吧,~~~~(>_<)~~~~ !! [html] view

Java5~11新特性

Java5~11版本新特性 Java5 Java6 Java7 Java8 Java9 Java10 Java11 Java5 Java5开发代号为Tiger(老虎),于2004-09-30发行 特性列表 泛型 枚举 自动装箱拆箱 可变参数 注解 foreach循环(增强for.for/in) 静态导入 格式化(System.out.println 支持%s %d等格式化输出) 线程框架/数据结构 JUC Arrays工具类/StringBuilder/instrument 1.泛型 所谓类型擦

[C++11新特性]第二篇

0.可变数量参数,可变函数模版,变长模版类 c++98可变数量参数 #include<cstdio> #include<cstdarg> double SumOfFloat(int count, ...) { va_list ap; double sum=0; va_start(ap,count); for(int i=0;i<count;i++) sum+=va_arg(ap,double); va_end(ap); return sum; } int main() { p

C++11新特性总结 (一)

1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++11的比较好的书籍.这篇文章仅总结关于C++11中的新东西,老的东西不再赘述.本文的所有代码仅仅值列出关键代码,并且所有特性都已经用编译器验证过,我的编译环境 gcc 5.3.1  g++ 5.3.1 ,据说 4.7以上的版本已经支持大部分C++11的特性,VS系列的编译器对C++11的支持情况不甚了

C++:C++11新特性超详细版(1)

前言: 虽然目前没有编译器能够完全实现C++11,但这并不意味着我们不需要了解,学习它.深入学习C++11,你会发现这根本就是一门新的语言,它解决了c++98中许多遗留下来的问题.早晚会有一天,C++11便会普及大部分编译器.因此,提早做些准备也是应该的. 在此我想做一个关于C++11的专题,将C++11的新特性进行一一讲解,以通俗易懂的语言及例子帮助读者入门C++11.本文便是C++11新特性超详细版系列文章的第一篇, 即C++:[C++11]新特性超详细版(1). 不过我要强调的是,这些文章