std::initializer_list的实现

3

我将代码从头文件initializer_list中复制,并将类名改为my_initializer_list

template<class _E>
    class my_initializer_list
    {
    public:
      typedef _E        value_type;
      typedef const _E&     reference;
      typedef const _E&     const_reference;
      typedef size_t        size_type;
      typedef const _E*     iterator;
      typedef const _E*     const_iterator;

    private:
      iterator          _M_array;
      size_type         _M_len;

      // The compiler can call a private constructor.
      constexpr my_initializer_list(const_iterator __a, size_type __l)
      : _M_array(__a), _M_len(__l) { }

    public:
      constexpr my_initializer_list() noexcept
      : _M_array(0), _M_len(0) { }

      // Number of elements.
      constexpr size_type
      size() const noexcept { return _M_len; }

      // First element.
      constexpr const_iterator
      begin() const noexcept { return _M_array; }

      // One past the last element.
      constexpr const_iterator
      end() const noexcept { return begin() + size(); }
    };

以及代码:

int main()
{
    my_initializer_list<int> foo = {1,2,3};

    return 0;
}

而且收到了错误提示:
could not convert '{1, 2, 3}' from '<brace-enclosed initializer list>' to 'my_initializer_list<int>'

我的问题:STL是如何实现initializer_list类的?


同样的原因,你不能复制粘贴std::typeinfo的定义,然后使用typeid来获取一个。 - user253751
1个回答

6
它与std::initializer_list一起使用,因为尽管std::initializer_list是一个类,但它不是一个常规的类。它是一个非常特殊的类,因为当您编写auto x = {1,2,3};时,编译器会推断xstd::initializer_list<int>并相应地进行初始化。编译器在这里进行了黑魔法以执行类型推断和初始化。它不仅是库功能,也是核心语言功能。
如果您要使用my_initializer_list,那么它的构造函数需要接受std::initializer_list,以便编译器可以为您执行黑魔法。
请注意,{1,2,3}是一个无类型表达式 - 好吧,严谨地说,它甚至不是一个表达式;只有在某些特殊情况下,它才能使用一些特殊的规则来初始化对象。例如,请参见以下内容:
auto items = {1,2,3}; //OK: items is inferred to be std::initializer_list<int>
                      //must #include <initializer_list>

然而,在模板的情况下,规则是不同的:

 template<typename T>
 void f(T const & items); 

 f({1,2,3}); //ILL-FORMED: T cannot be deduced to be
             //std::initializer_list<int> or anything else
             //even if you use #include <initializer_list>

 f(std::initializer_list<int>{1,2,3}); //OK: #include <initializer_list>

 f(std::vector<int>{1,2,3}); //OK: #include <vector>
                             //because std::vector accepts std::initializer_list<T>

希望这可以帮助到您。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接