首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >std::initializer_list的实现

std::initializer_list的实现
EN

Stack Overflow用户
提问于 2013-08-11 01:07:29
回答 2查看 5.5K关注 0票数 24

我一直在研究initializer_list是如何实现的,所以我找到了该标准的18.9节,并找到了一个看起来足够简单的接口。我认为制作我自己的版本(我将其命名为MyNamespace::InitializerList )和一个用例会很有启发性:

代码语言:javascript
复制
template<class T>
class ArrayPrinter
{
public:
    ArrayPrinter(MyNamespace::InitializerList<T> list)
    {
        for (auto i : list) cout << i << endl;
    }
};

...

ArrayPrinter ap{ {1,2,3} };

我惊讶地发现这不起作用,编译器抱怨说它找不到合适的构造函数(它想给我3个参数,但18.9节只描述了一个默认构造函数)。

经过一些修改之后,我发现我的类必须准确地命名为std::initializer_list才能工作。我也可以在MyNamespace中使用std::initializer_list别名,但不能将MyNamespace::InitializerList别名为std::initializer_list

看起来这并不是真正的language feature as it depends on the standard library

我的问题的要点是为什么名称如此重要,以及它试图传递给构造函数的3个参数是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-11 05:11:50

这个名字很重要,因为标准说它很重要。这个标准需要某种方式让你能够说,“这个构造函数可以传递一个包含T类型的值序列的带括号的初始化列表”。这种方式被命名为"std::initializer_list“。

您不能创建具有initializer_list的所有语言属性的类。您可以创建一个满足标准initializer.list.syn部分指定类型的条件。但是您会注意到,在那里指定的唯一构造函数是一个默认构造函数。创建包含实际元素的initializer_list的唯一方法依赖于编译器,而不是用户端代码。

所以你不能复制所有关于initializer_list的东西。就像你无法复制std::type_info一样。C++标准库不是可选的。

票数 25
EN

Stack Overflow用户

发布于 2020-07-10 17:54:59

这个答案并不完全准确。创建一个全功能的std::initializer_list是可能的--它只需要满足目标编译器的特定需求。

对于GCC和克朗来说,这个要求是私人的。下面是libc++的实现(碰巧在GCC 8.3中也能正常工作):

代码语言:javascript
复制
template<class _Ep>
class initializer_list
{
    const _Ep* __begin_;
    size_t    __size_;
    
    inline
    constexpr
    initializer_list(const _Ep* __b, size_t __s) noexcept
        : __begin_(__b),
          __size_(__s)
    {}
public:
    typedef _Ep        value_type;
    typedef const _Ep& reference;
    typedef const _Ep& const_reference;
    typedef size_t    size_type;
    
    typedef const _Ep* iterator;
    typedef const _Ep* const_iterator;
    
    inline
    constexpr
    initializer_list() noexcept : __begin_(nullptr), __size_(0) {}
    
    inline
    constexpr
    size_t    size()  const noexcept {return __size_;}
    
    inline
    constexpr
    const _Ep* begin() const noexcept {return __begin_;}
    
    inline
    constexpr
    const _Ep* end()   const noexcept {return __begin_ + __size_;}
};

template<class _Ep>
inline
constexpr
const _Ep*
begin(initializer_list<_Ep> __il) noexcept
{
    return __il.begin();
}

template<class _Ep>
inline
constexpr
const _Ep*
end(initializer_list<_Ep> __il) noexcept
{
    return __il.end();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18164353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档