好吧,也许从标题中不清楚我实际上在问什么。
我有一个带有初始化列表构造函数std::initializer_list<B>
的类。是否合法使用类D
的对象的初始化列表对其进行初始化,其中D
来自B
?
#include <initializer_list>
struct B {
B(int) {}
};
struct D: public B {
D(int s): B(s) {}
};
struct Foo {
Foo(std::initializer_list<B> l) {}
};
void main() {
Foo f{ D{ 1 }, D{ 2 } };
}
如果不合法,那是不是很糟糕?或者只是未定义的行为?
我在Visual Studio 2013 Update 1中尝试过该代码。它编译,但是当我运行它时,我可以看到(调试)如何:
D
创建了一个类D{1}
的对象(让我们调用tempD1
)。调用D
构造函数,然后调用B
构造函数。tempD1
的基础被移动到新的B
对象(tmpB1
):B
移动构造函数被调用。D{2}
(tmpD2
,tmpB2
)也是如此。Foo
初始化列表构造函数被调用。此时一切都很好。tmpB2
的析构函数被调用一次。tmpD2
的析构函数被调用两次。tmpD1
的析构函数被调用一次。我猜是编译器的一个错误(调用一个析构函数两次而错过另一个析构函数)。但我不确定是否使用std :: initializer_list是合法的。
(修正了关于'D'或'A'名称的混淆)
答案 0 :(得分:4)
从std::initializer_list<D>
到std::initializer_list<B>
的转换无效...
但构建std::initializer_list<B>
并使D
有效{(这就是这里发生的事情)......