为什么带有支撑初始化列表的Constructor/virtual析构函数不起作用?

bin*_*aba 2 c++ constructor virtual-destructor

为什么以下代码不编译?

#include <vector>

class Foo
{
public:
    Foo()
    { }

    virtual ~Foo()
    { }

    std::vector<int> aVec;
};


Foo bar =
{
    { 1, 2, 3, 4, 5 }
};
Run Code Online (Sandbox Code Playgroud)

以下代码编译时:

#include <vector>

class Foo
{
public:

    /*Foo()
    { }

    virtual*/ ~Foo()
    { }

    std::vector<int> aVec;
};


Foo bar =
{
    { 1, 2, 3, 4, 5 }
};
Run Code Online (Sandbox Code Playgroud)

除了参考语言规则外,请详细说明这些规则背后的基本原理.

为什么构造函数和虚拟析构函数的存在会因初始化而停止?

Ste*_*ner 5

因为Foo是类类型,所以支撑的初始化列表被视为聚合初始化.除其他外,这需要该类没有显式构造函数或虚拟成员:

聚合初始化是列表初始化的一种形式,它初始化聚合.聚合是以下类型之一:

类类型(通常是struct或union),有......

  • 没有私有或受保护的非静态数据成员

  • 没有用户提供,继承或显式(自C++ 17)构造函数(允许显式默认或删除构造函数)

  • 没有虚拟,私有或受保护的基类
  • 没有虚拟成员功能
  • 默认成员初始化程序


Fra*_*eux 5

您正在使用的列表初始化形式称为聚合初始化.它用于聚合类型.类型作为聚合的类型的要求之一是它没有用户提供的构造函数.

通过提供构造函数,编译器将尝试将列表初始化与定义的构造函数之一进行匹配.它更喜欢一个构造函数std::initializer_list.由于您没有提供一个,它将尝试查找与您的初始化列表提供的参数匹配的构造函数.由于唯一的构造函数是不带参数的默认构造函数,因此找不到匹配项.