为什么继承构造函数会破坏聚合体初始化?

3
为什么从基类继承构造函数会破坏聚合初始化?
例如,这样可以工作:
struct MyArray : std::array<int, 2ul> {};

MyArray a{1, 2};

但是这个不起作用:
struct MyArray : std::array<int, 2ul>
{
     using std::array<int, 2ul>::array;
};

MyArray a{1, 2};

你为什么期望它能工作呢?聚合体的重点在于它没有任何构造函数(默认/复制/移动除外)。那么你会期望 MyArray a{1, 2}; 是聚合初始化还是对(继承的)构造函数进行重载决议呢? - user17732522
1
等一下... std::array 没有构造函数。using std::array<int, 2ul>::array; 有任何意义吗? - user4581301
1
std::array拥有一个隐式生成的构造函数 - TheScore
1
@user4581301 std::array具有隐式默认、复制和移动构造函数。 - Ayxan Haqverdili
好的观点,但它没有一个可以接受initializer_list的构造函数,因此在一般情况下它并不无用,但在这里是无用的。我想知道不继承构造函数规则的基本原理是什么,是因为继承构造函数很难与用户定义的构造函数区分开来还是不能轻易地区分开来。 - user4581301
1个回答

1
自C++17起,聚合体可以具有基类,因此对于从其他类/结构派生的这种结构,允许使用列表初始化:
struct MoreData : Data {
    bool done;
};

MoreData y{{"test1", 6.778}, false};

C++17中,聚合体的定义为:

  • 数组
  • 或者是一个类类型(class、struct或union),该类类型满足以下条件:
    • 没有用户声明或显式构造函数
    • 没有通过using声明继承的构造函数
    • 没有非静态私有或保护数据成员
    • 没有虚函数
    • 没有虚拟、私有或保护基类

更多详细信息请参考Nicolai M. Josuttis所著《C++17 - The Complete Guide》中的第4章“聚合体扩展”。


重新考虑一下,这是如何解决问题的方法,而不是为什么它是个问题的解释。 - user4581301
我觉得这确实回答了我的问题,所以谢谢。using声明没有继承构造函数。 - rnorthcott
当时如果我知道你只是想要听“因为这就是规矩”的回答,我就会自己回答了。不过我仍然不确定是什么原因导致这个回答被踩了。 - user4581301

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接