C++11中新特性之:initializer_list详解

C++11提供的新类型,定义在<initializer_list>头文件中。

template< class T >
class initializer_list;

先说它的用处吧,然后再详细介绍一下。

首先有了initializer_list之后,对于STL的container的初始化就方便多了,比如以前初始化一个vector需要这样:

int a[] = {0, 1, 2, 3};
std::vector<int> vec(a, a+sizeof(a));

或者

std::vector<int> vec;
vec.push_back(1);
vec.push_back(3);
vec.push_back(3);
vec.push_back(2);

有了initializer_list后,就可以直接像初始化数组一样:

class Test {

private:
    static std::map<string, string> const nameToBirthday = {
        {"lisi", "18841011"},
        {"zhangsan", "18850123"},
        {"wangwu", "18870908"},
        {"zhaoliu", "18810316"},
    };
}

当然啦,里面的std::map必须提供参数为initializer_list的构造函数如:

map( std::initializer_list<value_type> init,
     const Compare& comp = Compare(),
     const Allocator& alloc = Allocator() );

其实for(initializer: list)中如果list是个形如:{a, b, c...},那么其实list自动被构造成了initializer_list对象。

下面稍微介绍一下initializer_list

一个initializer_list当出现在以下两种情况的被自动构造:

  1. 当初始化的时候使用的是大括号初始化,被自动构造。包括函数调用时和赋值
  2. 当涉及到for(initializer: list),list被自动构造成initializer_list对象

也就是说initializer_list对象只能用大括号{}初始化。

拷贝一个initializer_list对象并不会拷贝里面的元素。其实只是引用而已。而且里面的元素全部都是const的。

下面一个例子可以帮助我们更好的理解如何使用initializer_list:

#include <iostream>
#include <vector>
#include <initializer_list>

using namespace std;

template <class T>
struct S {
    vector<T> v;
    S(initializer_list<T> l) : v(l){
        cout << "constructed with a " << l.size() << "-elements lists" << endl;
    }
    void append(std::initializer_list<T> l) {
        v.insert(v.end(), l.begin(), l.end());
    }

    pair<const T*, size_t> c_arr() const{
        return {&v[0], v.size()};
    }

};

template <typename T>
void templated_fn(T arg) {
    for (auto a : arg)
        cout << a << " ";
    cout << endl;
}

int main() {
    S<int> s = {1, 2, 3, 4, 5}; //automatically construct a initializer_list
                                // object and copy it
    s.append({6, 7 , 8});         //list-initialization in function call

    cout << "The vector size is now " << s.c_arr().second << " ints:" << endl;

    for (auto n : s.v)
        cout << ‘ ‘ << n;
    cout << endl;

    cout << "range-for over brace-init-list: " << endl;

    for (auto x : {-1, -2, 03})   //// the rule for auto makes this ranged for work
        cout << x << " ";
    cout << endl;

    auto al = {10, 11, 12};  //special rule for auto

    cout << "The list bound to auto has size() = " << al.size() << endl;

    //templated_fn({1, 2, 3});   //compiler error! "{1, 2, 3}" is not an expressionit has no type, and so T cannot be duduced.

    templated_fn<initializer_list<int> > ({7, 8, 9}); //ok
    templated_fn<vector<int> >({3, 5, 7});           //also ok

    return 0;
}

Reference:

http://en.cppreference.com/w/cpp/utility/initializer_list

http://www.cppblog.com/liyiwen/archive/2009/07/26/91248.html

时间: 2024-10-11 16:03:24

C++11中新特性之:initializer_list详解的相关文章

h5新特性 File API详解

之前一直觉得h5的新特性就是一些新标签呢,直到想研究一下图片上传预览的原理,才发现还是有好多新的api的,只是不兼容ie低版本,挺可惜的, File API在表单中文件输入字段基础上,又添加了一些直接访问文件信息的接口.H5在DOM中为文件输入元素添加了一个files集合,在通过表单元素选择了一个或多个文件时,files集合中将包含一组file对象,每个file对象对应一个文件,每个file对象都有下列只读属性: 1.name:本地文件系统的文件名: 2.size:文件的字节大小: 3.type

Vue高版本中一些新特性的使用详解

一.深度作用选择器( >>> ) 严格来说,这个应该是vue-loader的功能."vue-loader": "^12.2.0" 在项目开发中,如果业务比较复杂,特别像中台或B端功能页面都不可避免的会用到第三方组件库,产品有时会想对这些组件进行一些UI方面的定制.如果这些组件采用的是有作用域的CSS,父组件想要定制第三方组件的样式就比较麻烦了. 深度作用选择器( >>> 操作符)可以助你一臂之力. 前端精品教程:百度网盘下载 ?

C++11中新特性之:lambda 表达式

首先摆出Lambda表达式语法 lambda-expression: lambda-introducer lambda-declaratoropt compound-statementlambda-introducer: [ lambda-captureopt ] lambda-capture: capture-default capture-list capture-default , capture-listcapture-default: & =capture-list: capture

C++11中新特性之:unordered_map

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value. 不同的是unordered_map不会根据key的大小进行排序,存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历. 所 以使用时map的key需要定义operator<.而unordered_map需要定义hash_value函数并且重载 operator==.但是很多系统内置

[C++11新特性] 智能指针详解

动态内存的使用很容易出问题,因为确保在正确的时间释放内存是极为困难的.有时我们会忘记释放内存产生内存泄漏,有时提前释放了内存,再使用指针去引用内存就会报错. 为了更容易(同时也更安全)地使用动态内存,新的标准库提供了两种智能指针类型来管理动态对象.智能指针的行为类似常规指针,区别在于它负责自动释放所指向的对象.这两种智能指针的区别在于管理底层指针的方式:shared_ptr允许多个shared_ptr类型指针指向同一个对象:unique_ptr则"独占"所指向的对象.标准库还定义了一个

Qt5 中对 C++11 一些新特性的封装

在 Qt5 中,提供更多 C++11 的特性支持,接下来我们将进行详细的说明. slots (槽) 的 Lambda 表达式 Lambda表达式 是 C++11 中的一个新语法,允许定义匿名函数.匿名函数可用于使用小函数作为参数,而无需显式的进行声明.之前可以通过编写函数指针来达到同样的目的. 在 Qt 4.8 中已经可在一些 QtConcurrent 函数中使用 Lambda 表达式了.但在 Qt5 中甚至可以通过 new connect syntax 来将 Lambda 表达式作为 slot

C++11 标准新特性:Defaulted 和 Deleted 函数

前两天写的铁字中提到了C++的删除函数,今天特地去网上查了查,转载了一篇不错的文章... 转载自 http://www.ibm.com/developerworks/cn/aix/library/1212_lufang_c11new/index.html C++11 标准新特性:Defaulted 和 Deleted 函数 本文将介绍 C++11 标准的两个新特性:defaulted 和 deleted 函数.对于 defaulted 函数,编译器会为其自动生成默认的函数定义体,从而获得更高的代

C++11 标准新特性: 右值引用与转移语义

C++ 的新标准 C++11 已经发布一段时间了.本文介绍了新标准中的一个特性,右值引用和转移语义.这个特性能够使代码更加简洁高效. 查看本系列更多内容 | 3 评论: 李 胜利, 高级开发工程师, IBM 2013 年 7 月 10 日 内容 在 IBM Bluemix 云平台上开发并部署您的下一个应用. 开始您的试用 新特性的目的 右值引用 (Rvalue Referene) 是 C++ 新标准 (C++11, 11 代表 2011 年 ) 中引入的新特性 , 它实现了转移语义 (Move

atitit.Oracle 9 10 11 12新特性attilax总结

atitit.Oracle 9  10 11  12新特性 1. ORACLE 11G新特性 1 1.1. oracle11G新特性 1 1.2. 审计 1 1.3. 1.   审计简介 1 1.4. 其他(大部分是管理功能) 2 2. Oracle 12c 的 12 个新特性 2 2.1. 2 Improved Defaults 增强了DEFAULT, default目前可以直接指代sequence了,同时增强了default充当identity的能力 2 2.2. Easy Top-N an