3

I copied the code from header file initializer_list and renamed the class name to 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(); } }; 

and the code:

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

and get the error:

could not convert '{1, 2, 3}' from '<brace-enclosed initializer list>' to 'my_initializer_list<int>' 

My question : How STL implement the initializer_list class?

1
  • Same reason you can't copy-paste the definition of std::typeinfo and then use typeid to get one. Commented Jan 27, 2017 at 5:17

1 Answer 1

7

It works withstd::initializer_list because even though std::initializer_list is a class, it is not a regular class. It is a very very special class, in the sense that when you write auto x = {1,2,3}; the compiler is going to infer x to be std::initializer_list<int> and initialize it accordingly. The compiler does black magic here to carry out the type-inference and initialization. It is not only library-feature. It is a core-langugage feature as well.

If you're going to use my_initializer_list instead, then its constructor needs to accept std::initializer_list so that the compiler can do the black magic for you.

Note that {1,2,3} is a type-less expression — well, to be pedantic, it is not even an expression; only in some special cases, it can be used to initialize objects using some special rules. For example, see this:

auto items = {1,2,3}; //OK: items is inferred to be std::initializer_list<int> //must #include <initializer_list> 

However, in case of templates, the rule is different:

 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> 

Hope that helps.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.