Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why we need a private constructor for std::initializer_list?

The suggested implementation of std::initializer_list in the standard and The C++ Programming Language are simple. By simple I mean there is nothing strange.
But things become complex in the Compilers implementation of std::initializer_list, for example, GCC has a private constructor for std::initializer_list with a comment above it which says: 'The compiler can call a private constructor.'. Here eerorika answered:std::initializer_list is special. So I looked for it in the compilers source code:

Clang:

  • AST/ExprCXX.h#L789
  • AST/StmtPrinter.cpp#L1935
  • AST/ItaniumMangle.cpp#4523

GCC:

  • cp/cp-tree.h#L2303
  • cp/init.c#L702
  • cp/call.c#L801

And I don't understand why do we need to have a special private constructor? I encountered this some time ago when I wanted to convert std::vector<T> to std::initializer_list<T>.

like image 778
Ghasem Ramezani Avatar asked Aug 11 '21 13:08

Ghasem Ramezani


Video Answer


1 Answers

The std::initializer_list is a reification of actual initializer-list, and its constructor is private simply to ensure no one is ever able to call it (except the compiler, of course), which prevents people from using std::initializer_list incorrectly.

As mentioned by StoryTeller; There is a gsl::span (or std::span in C++20) for contiguous range abstraction purpose. But it seems you try to (ab)use std::initializer_list for that instead.
(Which you can not as that is just a support type for {...} initialization.)


From comments:

... Couldn't it just be directly handled by the compiler itself? I mean something like a new keyword for it?

Well, a new keyword would potentially break existing codes, but the std namespace is a pretty safe place (for preventing conflicts).

like image 83
Top-Master Avatar answered Oct 19 '22 00:10

Top-Master