深入C++11 笔记

10 篇文章 1 订阅

深入应用C++11 笔记 (一)

第一章 程序简洁之道

1.1 类型推导
  1. auto类型推导 (auto–> 类型指示符 type-specifier)

    auto x=5;                //OK:x-->int
    auto pi=new auto(1); //OK:pi-->int*
    const auto *v=&x,u=6;    //OK:v-->const int*;u-->const int
    static auto y=0.0;       //OK:y-->double
    auto int r;              //error
    auto s;                  //error
  2. auto的限制

    void func(auto a=1){}            //error:auto不能用于函数参数
    struct Foo
    {
     auto var1_=0;                  //error:auto不能用于非静态成员变量
     static const auto var2_=0; //OK :var2_---->static const int
    };
    
    template<typename T>
    struct Bar{};
    
    int maint(void)
    {
     int arr[10]={0};
     auto aa=arr;                   //OK: aa-->int*
     auto rr[10]=arr;               //error :auto 无法定义数组
     Bar<int> bar;                  
     Bar<auto> bb=bar;              //error auto无法推导出模板参数
     return 0;
    }
  3. decltype 关键字

    • 获知表达式的类型 : decltype(exp) –>exp表示一个表达式(expression)
    • decltype是在编译器推导出一个表达式的类型(并不会正真计算表达式的值)
    int x=0;
    decltype(x) y=1;     //y-->int
    decltype(x+y) z=0;       //z-->int
    
    const int &i=x;
    decltype(i) j=y;         //j-->const int &
    
    const decltype(z) *p=&z;  //*p-->const int,p-->const int*
    decltype(z) *pi=&z;      //*pi-->int,pi-->int *
    decltype(pi) *pp=&pi;     //*pp-->int * ,pp-->int **
  4. 返回类型后置语法(auto 和decltype的结合使用)

    template<typename T,typename U>
    auto add(T t,U u) -> decltype(t+u)
    {
     return t+u;
    }
    int& foo(int &i);
    float foo(float &f);
    
    template<typename T>
    auto func(T &val) -> decltype(foo(val))
    {
     return foo(val);
    }
1.2 模板改进
  1. 模板的右尖括号(避免 连续两个尖括号(”>>”)会被翻译成右移操作符,而不是模板参数表的结束)

    template<int N>
    struct Foo
    {
     //........
    };
    
    Foo<(100 >> 2)> xx;//括号
  2. 模板的别名 using

    typedef std::map<std::string,int> map_int_t;
    typedef std::map<std::string,std::string> map_str_t;

    上面的场景中,其实我们需要的是一个固定以std::sting为key的map,它可以映射到int或另一个std:string

    //在C++98/03中 的写法如下:
    template<typename Val>
    struct str_map
    {
     typedef std::map<std::string,Val> type;
    };
    //.......
    str_map<int>::type map1;
    //C++11中出现了一个 可以重定义一个模板的语法 using
    template<typename Val>
    using str_map_t=std::map<std::string,Val>;
    //.....
    str_map_t<int> map1;

    通过using可以定义任意类型的模板表达方式,比如:

    template<typename T>
    using type_t = T;
    //....
    type_t<int> i;
    //type_t 实例化后的类型和它的模板参数类型等价。type_t<int>-->int
  3. 函数模板的默认模板参数

    在C++98/03中,类模板可以有默认的模板参数,如下:

    template<typename T,typename U=int,U N=0>
    struct Foo
    {
     //.....
    };

    但是却不支持函数的默认模板参数

    template<typename T=int>//error
    //error in C++98/03:default template argumments
    void func(void)
    {
     //.....
    }

    但是这一限制在C++11中被解除。上面的func函数可以在C++11中直接使用。

    int main(void)
    {
     func();//如同一个普通的void(void)类型函数
     return 0;
    }

    函数模板的默认模板参数没有必须卸载参数表的最后限制

    我们可以指定函数中的一部分模板参数采用默认参数,而另一部分使用自动推导:

    template<typename R=int,typename U>
    R func(U val)
    {
     return val;
    }
    int main(void)
    {
     auto type=func(123);
     return 0;
    }

    在调用函数模板时,若显示指定模板的参数,由于参数填充顺序是从右往左的,因此,像下面这样调用:

    func<long>(123);//func 的返回类型是long

    当默认模板参数和模板参数自动推导同时使用时,若函数模板无法自动推导出参数类型,则编译器将使用默认模板参数;否则将使用自动推导出的参数类型。例如:

    template<typename T>
    struct identity
    {
     typedef T type;
    };
    
    template<typename T=int>
    void func(typename identity<T>::type val,T=0)
    {
     //....
    }
    
    int main(void)
    {
     func(123); //T --> int
     func(123,123.0);   //T --> double
     return 0;
    }

    在上面例子中,通过identity外敷模板禁用了形参val的类型自动推导,但由于func指定了模板参数T的默认类型为int,因此,在fun(123)中,func的val参数将为int类型。而在func(123,123.0)中,由于func的第二个参数123.0位double类型,模板参数T将优先被自动推导位double。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值