std::initializer_list构造函数和“花括号初始化”存在问题

3

Consider the following code:

#include <initializer_list>

class C {
public:
    C() = delete;
    C(int) {}
};

class D {
public:
    D(std::initializer_list<C> il) {} 
};

int main()
{
    std::initializer_list<C> il{};  // fine: empty list, no need to construct C
    D d2(il);                       // fine: calls initializer_list ctor with empty list
    D d3{il};                       // ditto
    D d4({});                       // still fine
    D d5{{}};                       // error: use of deleted function 'C::C()' 
                                    // WHY is the constructor of 'C' required here?
}

我原以为D d5{{}};会使用空列表调用Dinitializer_list构造函数,且由于列表为空,C的构造函数不会被调用。然而,它无法编译:

错误:使用已删除的函数'C::C()' -- D d5{{}};

这个错误背后的原理是什么?

更新

在Scott Meyer的"Effective Modern C++"第55页上的一个问题让我认为,在花括号初始化中使用空括号将使用空列表调用initializer_list构造函数。这是错误的。有关详细信息,请参见作者的博客文章

可能是重复问题:https://dev59.com/UlsW5IYBdhLWcg3wM02F? - LogicStuff
1个回答

5

D d5{{}}; 试图使用一个元素的初始化列表来初始化 d5。这个元素是 {},它是 C{} 的简写 - 一个默认构造的 C 实例。但是 C 没有默认构造函数 - 因此出现了错误。


啊,你的意思是 D d5{{}}D d5{C{}} 是一样的吗? - sergej
@sergej 是的。实验上很容易证明 - 只需修改程序,使 C() 构造函数打印一些内容,和/或让 D 的列表构造函数打印列表的大小即可。 - Igor Tandetnik
@IgorTandetnik,您是如何诊断这个问题的?您是否像在评论中提到的那样,在构造函数中添加了“couts”? - PYA
1
@PYA 不,只是根据错误信息和基本原理。我还没有编译代码。 - Igor Tandetnik

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