3

根据本页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={};
}
4

2 回答 2

2

Myclass确实有一个默认构造函数;这只是被delete明确标记。所以值初始化的效果应该是:

  1. 如果 T 是一个没有默认构造函数或用户提供或删除的默认构造函数的类类型,则该对象是默认初始化的

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

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

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

然后Myclass没有默认构造函数;(并且由于其他用户声明的构造函数,没有隐式声明的默认构造函数)。然后执行列表初始化(如您所料),效果如下

所有std::initializer_list作为唯一参数或作为第一个参数(如果其余参数具有默认值)的构造函数都经过检查,并通过重载决议与单个类型参数进行匹配std::initializer_list

于 2020-10-15T07:57:10.147 回答
1

签出这篇文章。简而言之:

  • 如果默认构造函数被显式删除,编译器将假定不存在任何默认构造函数
  • 但是,如果您删除该Myclass() = delete;行,它将选择最好的构造函数,也就是您的构造函数initialized_list
于 2020-10-15T07:56:09.143 回答