C++11新特性 (列表初始化、变量类型推导)

目录

列表初始化

列表初始化支持的类型

变量类型推导

auto

decltype


列表初始化

        定义:无论是在初始化对象还是为对象赋新值时,将想要输入的值放入花括号就能为这个对象赋新值或初始化它,这就叫做列表初始化。

//普通
int num = 0;   //√
int num(0)     //√

//列表初始化:
int num = {0}  //√
//省略=也可以
int num{0}     //√

 不过这种初始化有一个重要特点:

如果我们使用列表初始化 初始值存在丢失信息的风险时 编译器将报错

例如:

double b = 3.1415926;
//此时编译器报错,因为double类型转为int有丢失的风险
int a{b};
int c = {b}; 

//但如果是普通初始化,虽然确实会丢失数据,但是不会报错
int a = b;   //a = 3
int c(b);    //c = 3

列表初始化支持的类型

        列表初始化支持内置类型自定义类型的单个对象初始化,对于自定义类型的多个对象初始化,我们需要用到一个系统自定义的类模板:initializer_list,该类模板中有三个方法:begin()、end()、以及size()。

        initializer_list中存储的都是常量值,不能改变,我们可以传一个initializer _list<模板类型>来遍历它进行赋值,来实现自定义类型的多个对象初始化。

        like:

#include <initializer_list>
template<class V>
class MyVector
{
public:
    MyVector(initializer_list<V> l):_capacity(l.size()),_size(0)
    {
        _array = new V[_capacity];
        //把传进来的值赋进去
        for(int i = 0; i < l.size();i++)
        {
            array[i] = l[i]
        }
    }

private:
    T* _array;
    size_t _size;
    size_t _capacity;
};

变量类型推导

        定义:变量类型推导就是在不明确需要用一个什么类型来接收等号右边的值的时候,编译器可以自己推导右边值的类型的一种机制。在C++11中,我们可以使用autodecltype来进行变量类型推导。

auto

        auto让编译器通过初始值来推算变量的类型,也就是auto定义的变量必须有初始值

//通过val1和val2相加的结果可以推断one的类型
auto one = val1 + val2;

//可以在一条语句中声明多个变量(!必须有初始值!)
auto i = 0,*p = i;   //正确 i是整型 p是整型指针

auto sz = 0,pi = 3.14  //错误 sz和p类型不一致

auto时如果是引用做初始值,那么auto推出的类型实际上是引用对象的类型,而不是这个引用,例:

int a = 1;
int& b = a;
auto c = b;  //此时c是int类型,而不是int&

当然如果auto后面加上引用符号,也可以生成引用

auto &b = a;  //此时b是a的引用

        auto一般会忽略顶层const,但是会保留底层const(关于顶层底层const会另作说明)

        我们来看一段代码理解:

int a = 1;
const int ca = a;
const int& cr = ca;

auto b = ca;  //b是一个int 而不是const int
auto c = cr;  //同上(因为cr也只是一个别名)
auto d = &a;  //d是一个整型指针
auto e = &ca; //e是一个指向const int的指针(此时为底层const)

 ps:范围for也是C++11新增加的特性,用auto实现~

vector<int> a = {1,2,3,4,5,6,7,8,9};
//遍历一整个vector
for(auto e:a)
{
    cout << e << ' ';
}
cout << endl;

输出为:1 2 3 4 5 6 7 8 9

decltype

        如果想要用表达式推断出的类型作为一个要定义的变量的类型,但是又不想初始化。我们可以使用decltype,它可以选择并返回操作数的数据类型,在这个过程中,编译器只是对表达式进行分析并得到它的类型,而没有实际的计算这个表达式

decltype(f()) sum = x; //sum的类型就是函数f的返回类型

        decltype和auto更多的不同之处在于,decltype不会对const或者引用做过多处理,可以看下面的代码加深理解:

int a = 1;
const int ca = a;
const int& cr = ca;

decltype(ca) b = ca;  //b是一个const int
decltype(cr) c = b;   //c是一个const int& (因为cr也是)
decltype(cr) d;       //此时的d错误,因为它是一个引用类型,引用类型必须初始化

如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型 

例如:

//r是一个int引用类型
decltype(r+0) a // 此时a是一个int而不是int&

显然r+0的表达式的结果会是一个具体值,而不是引用。


ps:decltype中有个很容易出错的地方

如果decltype里面的值单独加上一对圆括号,那么编译器就会把这个圆括号当成一个表达式。变量是一种可以作为赋值语句左值存在的特殊表达式,所以此时decltype的类型会变成引用。

int i = 1;
decltype((i)) a;  //此时a的类型是int&,编译器会报错,因为没有初始化
decltype(i) b;  //此时b的类型是int(未初始化)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值