7

I have some questions regarding the design of std::initializer_list. I didn't find answers in [support.initlist].

Why does it have an explicitly defined default constructor?

Why this constructor is not constexpr?

Why the method size() is not constexpr?

Why there's no traits giving the size of initializer_list (like specializing std::tuple_size)?

Why it's not possible to statically access its elements (like specializing std::get)?

What happens when sizeof is applied to initializer_list?

a.lasram
  • 4,371
  • 1
  • 16
  • 24
  • 8
    Why did I just imagine my 8-year old son machine-gunning me with questions about the sky being blue, where chocolate milk comes from, what gravity is... – John Dibling Jul 12 '13 at 20:03
  • 3
    @JohnDibling: Does your 8-year old son have a Stack Overflow account? No, you say? Are you sure? – thb Jul 12 '13 at 20:06
  • 7
    I think the reason for most of these things is that std::initializer_list isn't actually a container. It doesn't have value semantics, it has pointer semantics. It's only use is, at it name implies, to initialize objects. I think it was designed to be a lighter template than things like vector or tuple. – Borgleader Jul 12 '13 at 20:06
  • 2
    @JohnDibling Your metaphor is accurate:) I'm like the rooky asking the gods of c++ why they choose do so – a.lasram Jul 12 '13 at 20:08
  • 4
    @thb: Questions about minecraft and yu gi oh are off-topic at stack overflow, so I doubt it. :) – John Dibling Jul 12 '13 at 20:10
  • 1
    "Why it's not possible to statically access its elements (like specializing `std::get`)?" because `std::initializer_list` can be passed between compilation units without encoding its length in its type, unlike `std::tuple`. So the same reason as why we don't have `std::get` specialized for `std::vector` or any other random-access iterator or container: All existing uses `std::get` varies its return type depending on its input template argument integer. – Yakk - Adam Nevraumont Jul 12 '13 at 20:28
  • @Yakk - you're right: unlike std::array the size is not encoded in the type but assignments to initializer_list are fixed size and I don't see why the compiler cannot keep track of that size? (even if the object is passed to another compilation unit) – a.lasram Jul 12 '13 at 20:46
  • 1
    You want `std::initializer_list` users and constructors to be basically implicit templates on `std::initializer_list`, and constructor or function to be instantiated "remotely" depending on which `N` are used. That isn't easy for compilers to implement, and C++11 was designed to be easy for compilers to implement. Or, in short, the same reason why you cannot forward declare a `template` in a header, fully implement it in a `.cpp` file with no explicit instantiations, and in a completely different compilation unit instantiate it: nothing fundamental, it is just hard. – Yakk - Adam Nevraumont Jul 12 '13 at 21:43
  • @Yakk excellent example. your comments seem to answer all the questions not just "Why it's not possible to statically access its elements (like specializing std::get)?" – a.lasram Jul 12 '13 at 22:35
  • Nope: `constexpr` objects do not have those same issues. – Yakk - Adam Nevraumont Jul 12 '13 at 22:42

1 Answers1

3

From section 18.9 of the C++ Standard:

An object of type initializer_list 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 ]

I think the reason for most of these things is that std::initializer_list isn't actually a container. It doesn't have value semantics, it has pointer semantics. Which is made obvious by the last portion of the quote: Copying an initializer list does not copy the underlying elements. Seeing as they were intended solely for the purpose of initializing things, I don't think it's that surprising that you don't get all the niceties of more robust containers such as tuples.

Borgleader
  • 15,826
  • 5
  • 46
  • 62