为什么在初始化此类时未调用列表初始化?

问题描述

根据本页https://en.cppreference.com/w/cpp/language/value_initialization

中所述的值初始化

如果T是没有认构造函数但具有采用std :: initializer_list的构造函数的类类型,则将执行列表初始化。

所以我期望在下面的代码段中初始化类时将调用Myclass(const std::initializer_list<int> &l),但是编译器说

> the default constructor of "Myclass" cannot be referenced -- it is a deleted function

那是为什么?这是我在Windows上使用Mingw64 C ++ 11编译的代码

#include <iostream>
class Myclass {
    public:
     Myclass() = delete;
     Myclass(Myclass &&m) {}
     Myclass(const Myclass &m) {}
     Myclass(const std::initializer_list<int> &l) { std::cout << "initializer list"; }
};
int main(int argc,char const *argv[]) {
    Myclass m2 {};
     Myclass m1={};
}

解决方法

Myclass确实具有默认构造函数;只是明确标记为delete。因此,值初始化的效果应为:

  1. 如果T是没有默认构造函数或具有用户提供或删除的默认构造函数的类类型,则对象为default-initialized;

default-initialization中,选择了已删除的默认构造函数,并且程序格式错误。

如果不将默认构造函数声明为

class Myclass {
    public:
     // Myclass() = delete;
     Myclass(Myclass &&m) {}
     Myclass(const Myclass &m) {}
     Myclass(const std::initializer_list<int> &l) { std::cout << "initializer list"; }
};

然后Myclass没有默认的构造函数; (由于其他用户声明的构造函数,因此没有implicitly-declared default constructor)。然后执行list-initialization(如您所料),效果

检查所有将std::initializer_list作为唯一参数,或将第一个参数(如果其余参数具有默认值)作为第一个参数的构造函数,并用overload resolution与类型为{{1 }}

,

结帐this post。简而言之:

  • 如果默认构造函数被明确删除,则编译器将假定没有任何默认构造函数
  • 但是,如果您删除了Myclass() = delete;行,它将选择最佳的构造函数,也就是您的initialized_list