C++ initializer_list 高性能的stl 局部常量数组。

C++11引入了一个新的类模板 initializer_list。

它本质就是C 的局部常量数组的封装,避免了使用因为动态数组或vector而产生的在堆上分配、释放内存的额外开销,同时提供begin(),end(),size()的接口可以配合STL的容器和算法,这样可以减少代码量,如:方便地设计出支持变长数组的函数。

initializer_list的成员都是const的,语法上不支持修改,减少出错概率。如两个initializer_list可以赋值,指向相同的数组。

与std::array<>比,initializer_list更灵活,不需要指定N,减少模板类导致的代码膨胀。

#include <initializer_list>
#include <iostream>
#include <vector>
#include <array>
using namespace std;

//方便的数组访问
void print(initializer_list<int> &l) {
    cout << "size()=" << l.size() << endl;
    int *p=(int*)l.begin();//不安全
    *p = 888;
    for (int i : l) cout << i << " ";
    cout << endl;
}
//C数组访问需要传2个参数,容易出错
void print(int *a,int n) {
    cout << "size()=" << n<<endl;
    for (int i = 0; i < n;i++) cout << a[i] << " ";
    cout << endl;
}
void print(int a[]) {
    cout << "size()=" << a;
    //int n = end(a) - begin(a);//error
    //for (int i = 0; i < n; i++) cout << a[i] << " ";
    cout << endl;
}
int main() {
#define DATA {1,2,3,4}
    const int a[] = DATA;
    int b[] = DATA;
    auto l = DATA;//比数组定义还简单
    auto l2 = l;//l2,l指向同一块内存
    l2 = l;//l2,l指向同一块内存
    int n = end(a) - begin(a);
    cout << "&a=" << a << endl;
    cout << "&b=" << b << endl;
    cout << "i1.begin()=" << l.begin() << endl;
    cout << "&l=" << (void*)&l << endl;
    cout << "&l2=" << (void*)&l2 << endl;
    cout << "&a-&b="<<(int*)&a- (int*)&b << endl;
    cout << "&b-&l=" << (int*)&b - (int*)&l << endl;
    cout << "&b-l.begin()=" << (const int*)&b - (const int*)(l.begin()) << endl;
    cout << "&l2.begin()-l.begin()=" << (const int*)(l2.begin()) - (const int*)(l.begin()) << endl;
    print(l);
    
    //配合vector更方便
    vector<int> v1(begin(a),end(a));
    vector<int> v2(l);
    return 0;
}

 

/*输出

通过比较指针可以看到initializer_list的内存和数组的内存很接近,因而分析出initializer_list的数据内存都是在栈上。

&a=0053FA54
&b=0053FA3C
i1.begin()=0053FA14
&l=0053FA2C
&l2=0053FA04
&a-&b=6
&b-&l=4
&b-l.begin()=10
&l2.begin()-l.begin()=0
size()=4
888 2 3 4

*/

 

initializer_list 的实现代码也非常简单(VS2017)。

// initializer_list standard header (core)
#pragma once
#ifndef _INITIALIZER_LIST_
#define _INITIALIZER_LIST_
#ifndef RC_INVOKED
#include <cstddef>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,_STL_WARNING_LEVEL)
 #pragma warning(disable: _STL_DISABLED_WARNINGS)
 _STL_DISABLE_CLANG_WARNINGS
 #pragma push_macro("new")
 #undef new

_STD_BEGIN
        // CLASS TEMPLATE initializer_list
template<class _Elem>
    class initializer_list
    {    // list of pointers to elements
public:
    typedef _Elem value_type;
    typedef const _Elem& reference;
    typedef const _Elem& const_reference;
    typedef size_t size_type;

    typedef const _Elem* iterator;
    typedef const _Elem* const_iterator;

    constexpr initializer_list() noexcept
        : _First(nullptr), _Last(nullptr)
        {    // empty list
        }

    constexpr initializer_list(const _Elem *_First_arg,
        const _Elem *_Last_arg) noexcept
        : _First(_First_arg), _Last(_Last_arg)
        {    // construct with pointers
        }

    _NODISCARD constexpr const _Elem * begin() const noexcept
        {    // get beginning of list
        return (_First);
        }

    _NODISCARD constexpr const _Elem * end() const noexcept
        {    // get end of list
        return (_Last);
        }

    _NODISCARD constexpr size_t size() const noexcept
        {    // get length of list
        return (static_cast<size_t>(_Last - _First));
        }

private:
    const _Elem *_First;
    const _Elem *_Last;
    };

        // FUNCTION TEMPLATE begin
template<class _Elem>
    _NODISCARD constexpr const _Elem * begin(initializer_list<_Elem> _Ilist) noexcept
    {    // get beginning of sequence
    return (_Ilist.begin());
    }

        // FUNCTION TEMPLATE end
template<class _Elem>
    _NODISCARD constexpr const _Elem * end(initializer_list<_Elem> _Ilist) noexcept
    {    // get end of sequence
    return (_Ilist.end());
    }
_STD_END
 #pragma pop_macro("new")
 _STL_RESTORE_CLANG_WARNINGS
 #pragma warning(pop)
 #pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _INITIALIZER_LIST_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:0009 */
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值