c++11的重要特性2

可变参数模板在3中。

目录

​编辑

1、统一的列表初始化:

 std::initializer_list:

std::initializer_list是什么类型:

 std::initializer_list使用场景:

让模拟实现的vector也支持{}初始化和赋值

 2、声明

auto

decltype

nullptr

3、范围for循环

4、STL中一些变化

5、可变参数模板

递归获取

逗号表达式展开参数包


1、统一的列表初始化:

在C++98中,标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。比如:

​

    struct Point {
    int _x;
    int _y;
};
int main() {
    int array1[] = {1, 2, 3, 4, 5};
    int array2[5] = {0};
    Point p = {1, 2};
    return 0;
}

[点击并拖拽以移动]
​


C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自
定义的类型,使用初始化列表时,可添加等号(=),也可不添加:

class Date {
public:
    Date(int year, int month, int day) : _year(year), _month(month), _day(day) {
        cout << "Date(int year, int month, int day)" << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};
int main() {
    Date d1(2022, 1, 1); // old style
    // C++11支持的列表初始化,这里会调用构造函数初始化
    Date d2{2022, 1, 2};
    Date d3 = {2022, 1, 3};
    return 0;
}

创建对象时也可以使用列表初始化方式调用构造函数初始化 :

class Date {
public:
    Date(int year, int month, int day) : _year(year), _month(month), _day(day) {
        cout << "Date(int year, int month, int day)" << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};
int main() {
    Date d1(2022, 1, 1); // old style
    // C++11支持的列表初始化,这里会调用构造函数初始化
    Date d2{2022, 1, 2};
    Date d3 = {2022, 1, 3};
    return 0;
}

 std::initializer_list:

文档

std::initializer_list是什么类型:

 std::initializer_list使用场景:

std::initializer_list一般是作为构造函数的参数,C++11对STL中的不少容器就增加。 std::initializer_list作为参数的构造函数,这样初始化容器对象就更方便了。也可以作为operator= 的参数,这样就可以用大括号赋值。

int main() {
    vector<int> v = {1, 2, 3, 4};
    list<int> lt = {1, 2};
    // 这里{"sort", "排序"}会先初始化构造一个pair对象
    map<string, string> dict = {{"sort", "排序"}, {"insert", "插入"}};
    // 使用大括号对容器赋值
    v = {10, 20, 30};
    return 0;
}

让模拟实现的vector也支持{}初始化和赋值

namespace bit {
template <class T> class vector {
public:
    typedef T* iterator;
    vector(initializer_list<T> l) {
        _start = new T[l.size()];
        _finish = _start + l.size();
        _endofstorage = _start + l.size();
        iterator vit = _start;
        typename initializer_list<T>::iterator lit = l.begin();
        while (lit != l.end()) {
            *vit++ = *lit++;
        }
        // for (auto e : l)
        //    *vit++ = e;
    }
    vector<T>& operator=(initializer_list<T> l) {
        vector<T> tmp(l);
        std::swap(_start, tmp._start);
        std::swap(_finish, tmp._finish);
        std::swap(_endofstorage, tmp._endofstorage);
        return *this;
    }

private:
    iterator _start;
    iterator _finish;
    iterator _endofstorage;
};
} // namespace bit

 2、声明

auto

        在C++98中auto是一个存储类型的说明符,表明变量是局部自动存储类型,但是局部域中定义局部的变量默认就是自动存储类型,所以auto就没什么价值了。C++11中废弃auto原来的用法,将其用于实现自动类型推断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初 始化值的类型。

int main() {
    int i = 10;
    auto p = &i;
    auto pf = strcpy;
    cout << typeid(p).name() << endl;
    cout << typeid(pf).name() << endl;
    map<string, string> dict = {{"sort", "排序"}, {"insert", "插入"}};
    // map<string, string>::iterator it = dict.begin();
    auto it = dict.begin();
    return 0;
}

decltype

关键字decltype将变量的类型声明为表达式指定的类型。

// decltype的一些使用使用场景
template <class T1, class T2> void F(T1 t1, T2 t2) {
    decltype(t1 * t2) ret;
    cout << typeid(ret).name() << endl;//decltype返回括号里的结果(返回的)类型
}
int main() {
    const int x = 1;
    double y = 2.2;
    decltype(x * y) ret; // ret的类型是double
    decltype(&x) p;      // p的类型是int*
    cout << typeid(ret).name() << endl;
    cout << typeid(p).name() << endl;
    F(1, 'a');
    return 0;
}

nullptr

由于C++中NULL被定义成字面量0,这样就可能回带来一些问题,因为0既能指针常量,又能表示 整形常量。所以出于清晰和安全的角度考虑,C++11中新增了nullptr,用于表示空指针。

#ifndef NULL
#ifdef __cplusplus
#define NULL   0
#else
#define NULL   ((void *)0)
#endif
#endif

3、范围for循环

将容器遍历一遍,本质是调用迭代器,只要支持迭代器的就支持for循环,之前好像是迭代器章节讲过

4、STL中一些变化

方框中是新加容器

        容器中的一些新方法 如果我们再细细去看会发现基本每个容器中都增加了一些C++11的方法,但是其实很多都是用得 比较少的。

         比如提供了cbegin和cend方法返回const迭代器等等,但是实际意义不大,因为begin和end也是 可以返回const迭代器的,这些都是属于锦上添花的操作。

        实际上C++11更新后,容器中增加的新方法最后用的插入接口函数的右值引用版本:

请看下面的右值引用和移动语义章节的讲解。另外emplace还涉及模板的可变参数,也需要再继 续深入学习后面章节的知识。

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值