std::initializer_list 私有构造函数是不是从编译器得到非常特殊的处理?

Posted

技术标签:

【中文标题】std::initializer_list 私有构造函数是不是从编译器得到非常特殊的处理?【英文标题】:Does std::initializer_list private constructor get very special treatment from compiler?std::initializer_list 私有构造函数是否从编译器得到非常特殊的处理? 【发布时间】:2017-10-31 19:14:55 【问题描述】:

GCC 的 libstdc++ 的source code for std::initializer_list 有以下部分:

private:
  iterator                  _M_array;
  size_type                 _M_len;

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

这是如何发生的?为std::initializer_list 调用私有构造函数是硬编码到编译器代码中的特殊异常吗?或者 GCC 是否有一些内部功能可以潜在地用于暴露任何类的任何私有成员?

(我好像是relevant question,但它只提到了这一点

然而,initializer_list 是一种依赖于某种魔法的类型 由编译器完成。魔术,我指的是§8.5.4/5 你已经引用了。

这实际上并没有解释编译器是如何做到的。我的问题不在于我是否可以在我的代码中调用该构造函数,或者标准中允许什么,而是在内部 gcc 如何设法看到在这种情况下可以调用私有构造函数。)

【问题讨论】:

这怎么不是那个的复制品?稍后在您引用的the answer 中,它写道:“在这里,如 §8.5.4/5 中所述,编译器将创建一个包含四个整数的数组,然后使用一对指针(第一个元素和结束元素之后的元素)或指针和长度(libstdc++ 和 libc++ 似乎都是这样做的)。”这就解释了它是如何工作的 Is providing a private constructor for initializer_list conforming?的可能重复 @Justin,它没有解释 gcc 内部发生的事情。问题不在于我是否可以在我的代码中调用该构造函数,而是 gcc 如何在内部设法看到在这种情况下可以调用私有构造函数。 “正如 libstdc++ 私有构造函数定义上面的注释所暗示的,编译器能够发出绕过正常访问控制的代码” @Justin,但是编译器如何理解在这种情况下允许绕过?例如,initializer_list 是否在编译器源代码的某处硬编码? 【参考方案1】:

GCC 的 C++ 前端实际上并不使用该私有构造函数。 It uses no constructor at all:

/* Build up the initializer_list object.  */
totype = complete_type (totype);
field = next_initializable_field (TYPE_FIELDS (totype));
CONSTRUCTOR_APPEND_ELT (vec, field, array);
field = next_initializable_field (DECL_CHAIN (field));
CONSTRUCTOR_APPEND_ELT (vec, field, size_int (len));
new_ctor = build_constructor (totype, vec);

这实质上发出的代码只是将指针存储到initializer_list 对象的第一个字段中,并将大小存储到第二个字段中。

【讨论】:

以上是关于std::initializer_list 私有构造函数是不是从编译器得到非常特殊的处理?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 `std::initializer_list` 不提供下标运算符?

为啥 std::min(std::initializer_list<T>) 按值接受参数?

为啥 std::initializer_list 不是内置语言?

std::initializer_list 作为函数参数

如何将 C 数组转换为 std::initializer_list?

std::initializer_list 的实现