6

First part :

std::initializer_list is a really helpful feature of C++11, so I wondered how it is implemented in the standard library. From what I read here, the compiler creates an array of type T and gives the pointer to the initializer_list<T>.

It also states that copying an initializer_list will create a new object referencing the same data : why is it so ? I would have guessed that it either :

  • copies the data for the new initializer_list
  • moves ownership of the data to the new initializer_list

Second part :

From just one of many online references for the std::vector constructors:

vector (initializer_list<value_type> il,
    const allocator_type& alloc = allocator_type());

(6) initializer list constructor

Constructs a container with a copy of each of the elements in il, in the same order.

I am not comfortable with move semantics yet, but couldn't the data of il be moved to the vector ? I am not aware of the deep implementation of std::vector but IIRC it uses plain-old arrays.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 2
    Seems like another reason not to trust cplusplus.com. Delving into the standard, one eventually arrives at the initialiser-list ctor calling the pair-of-iterators ctor, which (using emplace construction) will move the elements if possible. – Angew is no longer proud of SO Jun 03 '13 at 10:29
  • 6
    cplusplus.com is a terrible, terrible site that does harm to the C++ community. Someone should smash the servers hosting it, burn the hard drives, encase them in concrete and sink them to the bottom of the ocean. – Jonathan Wakely Jun 03 '13 at 10:40
  • 1
    `What is the underlying structure of std::initializer_list?` Abstracted away from you, for good reason. – Lightness Races in Orbit Jun 03 '13 at 10:46
  • I was not referring to cplusplus.com as **the** reference (Bible), but I thought it was just an online edition of the standard. Thanks for warning about though, what flaws makes it "terrible" ? – teh internets is made of catz Jun 03 '13 at 10:56
  • 2
    @Angew I don't like having to defend that site, but it is correct in this case. `initializer_list` only provides read access to its elements. – R. Martinho Fernandes Jun 03 '13 at 13:45
  • @tehinternetsismadeofcatz I haven't perused it since a recent overhaul, but it used to have several errors and code examples that were either actually wrong or suggested bad ideas. I can't speak for the current content; nowadays I use a standard draft or cppreference.com (which is a wiki, so mistakes can be caught and fixed by the community) as my reference. – R. Martinho Fernandes Jun 03 '13 at 13:48
  • @R.MartinhoFernandes Ah, my bad. Thanks for correcting me. Seeing as I'm stuck with VS2010's version of C++11 for now, I haven't studied ILs in enough detail to be aware of this. – Angew is no longer proud of SO Jun 03 '13 at 14:00
  • Good question, I still don't see a satisfactory answer. To me, so far, it looks like `std::initializer_list` is a language feature and the `std::` part is misleading to make you think it is a library feature. Even looking at the code of initializer_list there is something strange about it that makes it a special object it seems. In fact in the GCC STL there is a comment that reads: ` // The compiler can call a private constructor.` This reinforces my belief that it is not a normal class. If this is true, I wonder if one can specialize it or extend it. – alfC Dec 15 '13 at 01:27

1 Answers1

12

What is the underlying structure of std::initializer_list?

Most likely, just a pair of pointers, or a pointer and a size. Paragraph 18.9/2 of the C++11 Standard even mentions this in a (non-normative) note:

An object of type initializer_list<E> provides access to an array of objects of type const E. [ Note: A pair of pointers or a pointer plus a length would be obvious representations for initializer_list. initializer_list is used to implement initializer lists as specified in 8.5.4. Copying an initializer list does not copy the underlying elements. —end note ]

Moreover:

I am not comfortable with move semantics yet, but couldn't the data of il be moved to the vector?

No, you can't move from the elements of an initializer_list, since elements of an initializer_list are supposed to be immutable (see the first sentence of the paragraph quoted above). That's also the reason why only const-qualified member functions give you access to the elements.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • 1
    Do note that technically a constructor such as `foo(foo const&&);` is a move constructor, and would in fact be called if you wrapped the iterators of an `std::initializer_list` in `std::move_iterator`s or used some such trickery. Such a constructor can rarely do anything useful (or different from what a standard *copy* constructor can do) though. – Luc Danton Jun 03 '13 at 10:55
  • @LucDanton: `foo(foo const&&)`... ew... :) But yes, technically you're correct. Still doesn't change the fact that elements of an `initializer_list` are meant to be immutable, so that "move constructor" won't be allowed to move anything without causing undefined behavior. – Andy Prowl Jun 03 '13 at 11:02
  • @AndyProwl: An initializer list can also contain variable references. In that case a move ctor moves the data of the referred element. So yes, the list itself is immutable (will always contain the same reference), but the move ctor can be useful. – Emilio Garavaglia Jun 03 '13 at 11:33
  • 1
    @EmilioGaravaglia: Strictly speaking, it cannot contain references, although it can contain `reference_wrapper`s. Then you would have to do: `foo x(std::move(static_cast(*l.begin())));`, which is getting contrived. – Andy Prowl Jun 03 '13 at 11:43
  • @AndyProwl: Yes, very contrived. They are clearly not designed to work that way... The problem is that `const` is not transitive as the `std::immutable` concept should be (but not standard yet: see D as an example of language where these two things are well given distinct keywords). This gives this *workarounds* some (sort of ) citizenship. Good point. – Emilio Garavaglia Jun 03 '13 at 13:01