好吧,也许从标题不清楚我实际上在问什么。
我有一个带有初始化列表构造函数的类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}
(let call )创建一个类对象tempD1
。D
构造函数被调用,然后是B
构造函数。- 的基础
tempD1
被移动到一个新B
对象(tmpB1
):B
调用移动构造函数。 - 第二个对象
D{2}
(tmpD2
,tmpB2
) 也是如此。 Foo
初始化列表构造函数被调用。此时一切都很好。- 的析构函数
tmpB2
被调用一次。 - 的析构函数
tmpD2
被调用两次。 - 的析构函数
tmpD1
被调用一次。
我猜是编译器的一个错误(调用一个析构函数两次而错过了另一个)。但我不确定 std::initializer_list 的使用是否合法。
(修复了关于“D”或“A”名称的混淆)