zoukankan      html  css  js  c++  java
  • (原创)C++11改进我们的程序之简化我们的程序(三)

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

    • 自动推断出类型
    auto i = 10; // 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>(0);
    c++11的写法
    auto ptr = make_shared<int>(0);
    
    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,欢迎大家来交流技术。

  • 相关阅读:
    23
    关系数据库范式
    组合
    排列
    bfs_迷宫求最短路径
    dfs-求连通块
    dfs_部分和问题
    线程
    http://m.blog.csdn.net/article/details?id=51699295
    jquery 页面多个倒计时
  • 原文地址:https://www.cnblogs.com/qicosmos/p/3297662.html
Copyright © 2011-2022 走看看