28

From [dcl.init.list]

The template std​::​initializer_­list is not predefined; if the header <initializer_­list> is not included prior to a use of std​::​initializer_­list — even an implicit use in which the type is not named — the program is ill-formed.

Since std​::​initializer_­list is special-cased by the compiler anyway, why is it not treated as a first-class syntax of the language?

My thoughts on some possibilities and its counter-arguments:

Namespace pollution

Could be solved just like std::size_t, the inclusion of the header only introduces the identifier.

Note how auto sz = sizeof(0); is well-formed even without the inclusion of any headers, as opposed to auto il = {1, 2, 3}; being ill-formed.

Compilation overhead

libstdc++ implementation of std::initializer_list is literally less than 50 lines with no dependency on other headers. How big of overhead can that be?

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Passer By
  • 19,325
  • 6
  • 49
  • 96
  • 3
    Maybe it's to let old code avoid implicit list initialization where it would otherwise be ambiguous or undesired? – Useless Mar 19 '18 at 17:38
  • 3
    Another example is `typeid` (needing `std::type_info`), as well as `<=>` in C++2a. – Kerrek SB Mar 19 '18 at 17:58
  • 6
    During `<=>`'s discussion, a maintainer of a popular implementation stated that it is infeasible for their compiler to synthesize the entire class type result of `<=>`. Synthesizing an entire class template would seem to be even more out of reach. – T.C. Mar 19 '18 at 18:18
  • Modularity; and the C++ way. It is not a keyword, and not a real template. – Shmuel H. Mar 19 '18 at 18:46
  • A bit of research into old minutes from a decade ago didn't reveal a reason, although it was stated in one of Bjarne's papers that braced initializer lists should be "opt-in" basically, what @Useless said. – Rakete1111 Mar 19 '18 at 18:57
  • @Useless As far as I'm aware, list initialization wasn't a breaking change. It wasn't legal to write `std::vector v{1, 2};` nor `auto il = {1, 2};` before C++11. The only possibility of ambiguity is aggregates, but the semantics are preserved there. – Passer By Mar 19 '18 at 19:43
  • You could equally consider `std::cout` as a "first-class" part of C++ since it's UB to add your *own* stuff to that namespace, so the only possible `cout` that could be in there is the `iostream` one. So why is using `std::cout` invalid if you don't include ``? :-) – paxdiablo Jul 29 '18 at 04:29
  • 3
    @paxdiablo `std::cout` has the semantics of a user defined object. `std::initializer_list` doesn't, the language rules have ridiculously many special cases to accommodate it. – Passer By Jul 29 '18 at 05:11
  • 1
    Ftr, the relevant proposal is [here](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2640.pdf), though I did not find a rationale for the wording. – Baum mit Augen Jun 29 '19 at 20:10
  • @Baum mit Augen♦: look at its date. It was proposed as an IMO desperate temporary solution; hoping that further language modifications allow an implementation or alternative, but it looks to have been forgotten later on. – Red.Wave Aug 05 '20 at 23:02
  • 1
    The consistency with `typeid` and `<=>` has a counter-example: there's no `#include ` to use `operator()()`, `operator+()` or copy constructor of `[]{}` – Alex Guteniev Aug 31 '20 at 18:26

1 Answers1

1

It seems that there is no rational behind it. Maybe at the time there was an hope that further language resolutions and modifications allow an implementation, but this doesn't seems real now.

In any case further reading about the argument can be found here.

Zig Razor
  • 3,381
  • 2
  • 15
  • 35