聚合初始化派生类

时间:2018-01-23 12:49:38

标签: c++ initialization

以下代码无法使用Visual Studio2017或在线GDB进行编译。我期望它编译,因为迭代器只是一个类型的类,它是公开继承的。这是不允许的还是在VS2017中不起作用?

template<typename T>
struct Gen : public std::iterator<std::input_iterator_tag, T>
{
    T value;
};

int main()
{   
    Gen<int> g = Gen<int>{ 10 }; // this doesnt
    Gen<int> g2 = Gen<int>{ {}, 10 }; // neither does this
}

错误是

  

错误C2440&#39;初始化&#39;:无法转换为&#39;初始化列表&#39;至   &#39;根&#39;

1 个答案:

答案 0 :(得分:10)

什么

Gen<int> g = Gen<int>{ 10 };

尝试做的是调用不存在的Gen<int>(int)构造函数。您要做的是聚合初始化,其语法为:

Gen<int> g = { {}, 10 };

only works since C++17用于派生类型:

  

如果initializer子句是嵌套的braced-init-list(不是表达式),则相应的数组元素/类成员 / public base(自C ++ 17)是列表 - 从该子句初始化:聚合初始化是递归的。

有关详细信息,聚合初始化在以下标准部分中定义。

  

[dcl.init.list]/3

     
      
  1. 对象或类型T的引用的列表初始化定义如下:
      3.1如果 braced-init-list 包含 specified-initializer-list ,则T应为聚合类。
  2.   

  

[dcl.init.aggr]/1

     

聚合是一个数组或类(第12条)与
  1.1没有用户提供的,显式的或继承的构造函数(15.1),
  1.2没有私人或受保护的非静态数据成员(第14条),
  1.3无虚函数(13.3)和
  1.4没有虚拟,私有或受保护的基类(13.1)。

因为继承自std::iterator<std::input_iterator_tag, T>