简体   繁体   中英

Is providing a private constructor for initializer_list conforming?

This draft standard shows the synopsis for initializer_list . It has no private constructor.

http://i.stack.imgur.com/5bc61.png

But two standard library implementations I have looked at, libstdc++ and libc++, both provide private constructors:

  // The compiler can call a private constructor.
  constexpr initializer_list(const_iterator __a, size_type __l)
  : _M_array(__a), _M_len(__l) { }

_LIBCPP_ALWAYS_INLINE
_LIBCPP_CONSTEXPR_AFTER_CXX11
initializer_list(const _Ep* __b, size_t __s) _NOEXCEPT
    : __begin_(__b),
      __size_(__s)
    {}

I believe the part where this private constructor is "implied" stems from §8.5.4/5:

An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation allocated a temporary array of N elements of type const E , where N is the number of elements in the initializer list. Each element of that array is copy-initialized with the corresponding element of the initializer list, and the std::initializer_list<E> object is constructed to refer to that array.

So my questions are:

  • Is the synopsis under-specified?

  • Does the library need a private constructor? What does it do that the compiler can't?

Is the synopsis under-specified?

No, it documents the user-facing bits of the initializer_list class template, the parts you're actually allowed to make use of in your code. According to the synopsis the template only contains a default constructor, allowing you to create empty initializer_list s, which is clearly not very useful. However, initializer_list<T> is a type that depends on some magic being done by the compiler. By magic, I'm referring to §8.5.4/5 that you've quoted. This allows the following statement to be legal and compile.

std::initializer_list<int> numbers{1, 2, 3, 4}; // no such constructor in the synopsis

Here, as explained in §8.5.4/5, the compiler will create an array containing the four integers, and then initialize the initializer_list<int> instance with either a pair of pointers (first element and one past the end element) or a pointer and length (which is what both libstdc++ and libc++ seem to do).

Once the instance has been created, your code is allowed to access all the member functions listed in the synopsis.

Does the library need a private constructor? What does it do that the compiler can't?

As the comment above the libstdc++ private constructor definition implies, the compiler is capable of emitting code that bypasses normal access control, so no, I'd say it's not essential to have that constructor. The compiler could use the default constructor to construct an empty initializer_list instance, and then assign appropriate values to the private data members (these aren't listed in the synopsis either, but are necessary).

But why bother with that clumsiness when a private constructor provides a clean interface that the compiler can call?

The question boils down to whether an implementation may define something beyond what the standard dictated. Yes, that is possible.

Indeed §17.6.5.5 (draft n° 3797) states:

A call to a member function signature described in the C ++ standard library behaves as if the implementation declares no additional member function signatures.

Footnote 189:

189) A valid C++ program always calls the expected library member function, or one with equivalent behavior. An implementation may also define additional member functions that would otherwise not be called by a valid C++ program.

You are not allowed to call to call those additional member functions, even if they were accessible.

Regarding std::initializer_list

Does the library need a private constructor? What does it do that the compiler can't?

The standard defines what you'd expect when constructing a std::initializer_list<T> from an initializer list. The way it's done is implementation-defined and, for what said above, it may therefore call a private constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM