嗯,也许从标题看不清楚我到底在问什么。
我有一个带有初始化列表构造函数的类 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”名称的混淆)
最佳答案
来自 std::initializer_list<D>
的转换至 std::initializer_list<B>
无效...
但是构建一个 std::initializer_list<B>
与一些D
是有效的(这就是这里发生的事情)...
但是你会得到object slicing
关于c++ - 合法使用 initializer_list 来初始化具有派生类型的对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21731601/