该标准草案显示了以下内容的概要:initializer_list
。它没有私有构造函数。
但我看过的两个标准库实现 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)
{}
我相信这个私有构造函数“隐含”的部分源于§8.5.4/5:
类型的对象std::initializer_list<E>
是由一个
初始化列表就像实现分配了一个临时数组一样
的N类型元素const E
, where N是元素的数量
在初始化列表中。该数组的每个元素是
使用初始化器的相应元素进行复制初始化
列表,以及std::initializer_list<E>
对象被构造为
引用该数组。
所以我的问题是:
剧情简介是否不够详细?
不,它记录了面向用户的部分initializer_list
类模板,您实际上可以在代码中使用的部分。根据概要,模板仅包含一个默认构造函数,允许您创建空initializer_list
s,这显然不是很有用。然而,initializer_list<T>
是一种依赖于某些的类型magic由编译器完成。神奇的是,我指的是您引用的§8.5.4/5。这使得下面的语句合法并且可以编译。
std::initializer_list<int> numbers{1, 2, 3, 4}; // no such constructor in the synopsis
这里,如§8.5.4/5中所述,编译器将创建一个包含四个整数的数组,然后初始化initializer_list<int>
具有一对指针(第一个元素和一个超过结束元素)或一个指针和长度(这就是 libstdc++ 和 libc++ 似乎所做的)的实例。
创建实例后,您的代码就可以访问概要中列出的所有成员函数。
库需要私有构造函数吗?它做了哪些编译器不能做的事情?
正如 libstdc++ 私有构造函数定义上面的注释所暗示的那样,编译器能够发出绕过正常访问控制的代码,所以不,我想说拥有该构造函数并不是必需的。编译器可以使用默认构造函数来构造一个空的initializer_list
实例,然后为私有数据成员分配适当的值(这些也没有在概要中列出,但是必要的)。
但是,当私有构造函数提供编译器可以调用的干净接口时,为什么要为这种笨拙而烦恼呢?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)