这次要讲的是:C++11如何通过auto、decltype和返回值后置来简化我们的程序。
  auto和c#中的var类似,都是在初始化时自动推断出数据类型。当某个变量的返回值难于书写时,或者不太确定返回的数据类型时,或者不关心返回的数据类型时用auto,让编译器自动帮我们推断出类型来。例如:

  • 自动推断出类型
auto i = ; // i is an int
auto str = "a"; // str is a string
auto p = new A(); // p is a foo* auto f = [](int x){return x;}; //f is function<int(int)>
auto f = std::bind(&A::Test, &A); //f is member function
  • 简化类型的写法
c++11之前
std::shared_ptr<int> ptr = make_shared<int>();
c++11的写法
auto ptr = make_shared<int>(); c++11之前
boost::unordered_multimap<uint32_t, int> map;
获取equal_range返回值时需要这样定义:
std::pair<boost::unordered_multimap<uint32_t, int>::iterator, boost::unordered_multimap<uint32_t, int>::iterator> range = map.equal_range(key); c++11的写法
auto range=m_taskClientMap.equal_range(key);
  • 简化变量的写法
不用auto的写法
std::function<void (char*, int)> f = std::bind(&ReadHandler::ConnectPreProcess, this, std::placeholders::_1, std::placeholders::_1); 用auto简化
auto _1 = std::placeholders::_1;
auto _2 = std::placeholders::_2;
auto f = std::bind(&ReadHandler::ConnectPreProcess, this,_1, _2);
  • auto作为迭代器类型,遍历集合
std::map<std::string, std::vector<int>> map;
for(auto it = begin(map); it != end(map); ++it)
{
}

通过上面的例子,我们看到auto使用起来真的很方便,简化了很多,原来几行代码现在一行就搞定,还帮我自动推断出类型。其实auto还有一个强大之处,在介绍它的另一个特性之前先看看decltype。

decltype用于查询表达式的数据类型,常用来解决难以确定某些表达式类型的问题。例如:

const int&& foo();
const int bar();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1; // 类型为const int&&
decltype(bar()) x2; // 类型为int
decltype(i) x3; // 类型为int
decltype(a->x) x4; // 类型为double
decltype((a->x)) x5; // 类型为const double&

通过上面的例子我们可以看到decltype就是根据一个左值或者右值来推断出其类型。回到刚才说的auto另外一个特性:返回值占位。因为有时候在泛型编程时,有些函数的返回类型难以确定,使用auto后,将由编译器自动进行确定。例如:

template<typename U, typename T>
R Add(U u, T t)
{
auto val = u + t;
return val;
}

这个返回值我们难以确定,c++11通过返回值后置来解决这个问题,它通过auto作为一个返回值占位符,返回值类型在稍后通过decltype推断出来。

template<typename U, typename T>
auto Add(U u, T t)->decltype(u+t)
{
auto val = u + t;
return val;
}

至于为什么需要将返回值类型后置,这里简单说明一下。如果没有后置,则函数声明为decltype(u+t) Add(U u,T t),但
此时模板参数t和u还未声明,编译无法通过。另外,如果非要使用返回值类型前置的形式,也可以将函数声明为decltype((*(U*)0)+(*(T *)0)) Add(U u, T t),但这种形式比较晦涩难懂,因此不推荐采用。

auto和decltype在很多方面简化了我们的代码,让我们写代码的时候不必为类型难以推断或者难以书写而烦恼,让我们可以尽情享受编程的乐趣!

c++11 boost技术交流群:296561497,欢迎大家来交流技术。

(原创)C++11改进我们的程序之简化我们的程序(三)的更多相关文章

  1. (原创)C++11改进我们的程序之简化我们的程序(八)

    本次要讲的是如何通过泛型函数来简化我们的程序. 泛型函数除了之前介绍的一些优点外还有两个重要的优点 1.消除重复逻辑,提高程序的内聚性和健壮性 泛型函数在某种程度上用来弥补泛型类型的不足.通过泛型类型 ...

  2. (原创)C++11改进我们的程序之简化我们的程序(二)

    这次要讲的是:C++11如何通过组合函数来简化我们的程序.关于组合函数,大家可能对这个概念有点陌生.组合函数是将N个一元函数组成一种更复杂的函数,每个函数的返回值作为参数传给下一个函数,直到传到最后一 ...

  3. C++11改进我们的程序之简化我们的程序1

    C++11改进我们的程序之简化我们的程序(一) C++11在很多方面可以简化我们的程序开发,我会在“简化我们的程序”这一系列的博文中一一讲到,敬请关注.这次要讲的是:C++11如何通过获取函数模板的返 ...

  4. (原创)C++11改进我们的程序之简化我们的程序(四)

    这次要讲的是:c++11统一初始化.统一begin()/end()和for-loop循环如何简化我们的程序 初始化列表 c++11之前有各种各样的初始化语法,有时候初始化的时候还挺麻烦,比较典型的如v ...

  5. (原创)C++11改进我们的程序之简化我们的程序(一)

    C++11在很多方面可以简化我们的程序开发,我会在“简化我们的程序”这一系列的博文中一一讲到,敬请关注.这次要讲的是:C++11如何通过获取函数模板的返回值类型来简化我们的程序.在谈到简化之前,我们先 ...

  6. (原创)c++11改进我们的模式之改进代理模式,实现通用的AOP框架

    c++11 boost技术交流群:296561497,欢迎大家来交流技术. 本次要讲的时候如何改进代理模式,具体来说是动态代理模式,动态代理模式一般实现AOP框架,不懂AOP的童鞋看这里.我前面的博文 ...

  7. (原创)c++11改进我们的模式之改进命令模式

    模式虽然精妙,却难完美,比如观察者模式中观察者生命周期的问题:比如访问者模式中循环依赖的问题等等:其它很多模式也存在这样那样的一些不足之处,如使用场景受限.实现复杂.不够简洁.不够通用等.但我觉得不足 ...

  8. (原创)c++11改进我们的模式之改进访问者模式

    本次讲c++11改进我们的模式之改进访问者模式 访问者模式是GOF23个设计模式中比较复杂的模式之一,但是它的功能也很强大,非常适合稳定的继承层次中对象的访问,可以在不修改被访问对象的情况下,动态添加 ...

  9. (原创)C++11改进我们的程序之简化我们的程序(七)

    这次要讲的内容是:c++11中的tuple(元组).tuple看似简单,其实它是简约而不简单,可以说它是c++11中一个既简单又复杂的东东,关于它简单的一面是它很容易使用,复杂的一面是它内部隐藏了太多 ...

随机推荐

  1. 【laravel5.4】安装predis

    1.服务器先安装redis-server,这是毋庸置疑的!!! 2.服务器开启redis-server,配置相关参数 3.laravel执行 : $  yourPhpPath composer.pha ...

  2. k8s oomkilled超出容器的内存限制

    超出容器的内存限制 只要节点有足够的内存资源,那容器就可以使用超过其申请的内存,但是不允许容器使用超过其限制的 资源.如果容器分配了超过限制的内存,这个容器将会被优先结束.如果容器持续使用超过限制的内 ...

  3. libgdx游戏引擎教程

    第一讲:libgdx游戏引擎教程(一)性能优良的游戏引擎—libgdx http://www.apkbus.com/android-57355-1-1.html 第二讲: libgdx游戏引擎教程(二 ...

  4. webDriver.Close() 和 webDriver.Quit() 、webDriver.Dispose() 的区别

    1. webDriver.Close() - Close the browser window that the driver has focus of //关闭当前焦点所在的窗口2. webDriv ...

  5. TCP连接建立与释放

    tcp建立连接 tcp连接的建立需要经历”三次握手“的过程.过程如下 client发送SYN包(值为j)以及SEQ包到server端,此时client进入SYN_SEND状态.此为第一次握手. ser ...

  6. shell中$#等含义

    $# 是传给脚本的参数个数 $0 是脚本本身的名字 $1 是传递给该shell脚本的第一个参数 $2 是传递给该shell脚本的第二个参数 $@ 是传给脚本的所有参数的列表 $* 是以一个单字符串显示 ...

  7. 如何在Android Studio项目中导入开源库?

    前两天,谷歌发布了Android Studio 1.0的正式版,也有更多的人开始迁移到Android Studio进行开发.然而,网上很多的开源库,控件等还是以前的基于Eclipse进行开发,很多人不 ...

  8. visual studio 设置代码注释模板

    1.C#模板文件: 路径:C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\ItemTemplates\CSharp\Co ...

  9. php,perl计算crc

    PHP版: <?php echo getCrc32("/var/www/html/resource/koc_data/2013_03/01/1ck65e.koc") ; # ...

  10. 利用eclipse+jdk1.8搭建Java开发环境(超具体的)

    利用eclipse+jdk1.8搭建Java开发环境 转载请声明出处:http://blog.csdn.net/u013067166/article/details/50267003 引言:eclip ...