为initializer_list符合提供了一个私有构造函数? [英] Is providing a private constructor for initializer_list conforming?

查看:207
本文介绍了为initializer_list符合提供了一个私有构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此标准草案显示 initializer_list 的摘要。它没有私有构造函数。





<

  //编译器可以调用私有构造函数。 
constexpr initializer_list(const_iterator __a,size_type __l)
:_M_array(__ a),_M_len(__ l){}

_LIBCPP_ALWAYS_INLINE
_LIBCPP_CONSTEXPR_AFTER_CXX11
initializer_list _Ep * __b,size_t __s)_NOEXCEPT
:__begin _(__ b),
__size _(__ s)
{}


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


类型 std :: initializer_list< E> 的对象由
初始化程序列表构成,如同实现分配了临时数组
const E N 元素,其中 N 是初始化器列表中元素
的数量。该数组的每个元素是用初始化器
list的相应元素进行复制初始化的
,并且 std :: initializer_list< E> 构造成
引用该数组。


所以我的问题是:


$ b $



解决方案


概要是否低于规定?


不,它会记录 initializer_list 类模板,你实际上允许在你的代码中使用的部分。根据概要,模板只包含默认构造函数,允许创建空 initializer_list s,这显然不是很有用。但是, initializer_list< T> 是一种依赖于编译器执行的一些 magic 类型。通过魔法,我指的是你引用的§8.5.4/ 5。这允许以下语句合法并编译。

  std :: initializer_list< int>数字{1,2,3,4}; //概要中没有这样的构造函数

这里,如第8.5.4 /编译器将创建一个包含四个整数的数组,然后用一对指针(第一个元素和一个指针通过结束元素)初始化 initializer_list< int> 指针和长度(这是libstdc ++和libc ++似乎都做的)。



一旦实例被创建,你的代码被允许访问所有成员函数


库需要一个私有构造函数吗?编译器不能做什么?


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



但是,当私有构造函数提供一个干净的接口,编译器可以调用时,为什么要麻烦呢?


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

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_lists, 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?

这篇关于为initializer_list符合提供了一个私有构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆