是否为initializer_list提供了一个私有构造函数?

use*_*874 8 c++ c++-standard-library language-lawyer c++11

该标准草案显示了该概要initializer_list.它没有私有构造函数.

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

但是我看过的两个标准库实现,libstdc ++和libc ++都提供了私有构造函数:

  // 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)
    {}
Run Code Online (Sandbox Code Playgroud)

我相信这个私有构造函数"隐含"的部分源于§8.5.4/ 5:

类型的对象std::initializer_list<E>是从初始化列表构造的,就好像实现分配了N个元素类型的临时数组const E,其中N是初始化列表中的元素数.使用初始化列表的相应元素对该数组的每个元素进行复制初始化,并std::initializer_list<E>构造该对象以引用该数组.

所以我的问题是:

  • 简要说明不明确吗?

  • 该库是否需要私有构造函数?编译器不能做什么?

Pra*_*ian 2

\n

剧情简介是否不够详细?

\n
\n\n

不,它记录了类模板中面向用户的部分initializer_list,即您实际上可以在代码中使用的部分。根据概要,模板仅包含一个默认构造函数,允许您创建空的initializer_lists,这显然不是很有用。然而,initializer_list<T>它是一种依赖于编译器所做的一些魔法的类型。通过魔术,我指的是您引用的 \xc2\xa78.5.4/5 。这使得以下语句合法并且可以编译。

\n\n
std::initializer_list<int> numbers{1, 2, 3, 4}; // no such constructor in the synopsis\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这里,如 \xc2\xa78.5.4/5 中所述,编译器将创建一个包含四个整数的数组,然后initializer_list<int>使用一对指针(第一个元素和末尾元素之后的一个)或一个指针和长度(libstdc++ 和 libc++ 似乎都是这样做的)。

\n\n

创建实例后,您的代码就可以访问概要中列出的所有成员函数。

\n\n
\n

库需要私有构造函数吗?它做了哪些编译器不能做的事情?

\n
\n\n

正如 libstdc++ 私有构造函数定义上面的注释所暗示的那样,编译器能够发出绕过正常访问控制的代码,所以不,我想说拥有该构造函数并不是必需的。编译器可以使用默认构造函数来构造一个空initializer_list实例,然后为私有数据成员分配适当的值(这些值也没有在概要中列出,但是必要的)。

\n\n

但是,当私有构造函数提供编译器可以调用的干净接口时,为什么要为这种笨拙而烦恼呢?

\n