是否合法使用initializer_list来初始化派生类型的对象? [英] Is legal use initializer_list to initialize an object with derived types?
问题描述
我有一个类带有初始化列表构造函数 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 $ c $
- An object of class
D
is created for the first objectD{1}
(let calltempD1
).D
constructor is invoked and then theB
constructor. - The base of
tempD1
is moved to a newB
object (tmpB1
):B
move constructor is invoked. - The same for the second object
D{2}
(tmpD2
,tmpB2
). Foo
initializer-list constructor is invoked. All fine at this point.- destructor of
tmpB2
is invoked once. - destructor of
tmpD2
is invoked twice. - destructor of
tmpD1
is invoked once.
我猜是编译器的一个错误(调用一个析构函数两次,缺少另一个)。但我不知道如果使用std :: initializer_list是合法的。
(修正关于'D'或'A'名称的混淆)
从 std :: initializer_list< D>
到 std :: initializer_list< B>
的转换有效...
并且用 D
构造 std :: initializer_list< B>
有效...
但您将拥有对象切片
Well, maybe from the title is not clear what I'm actually asking.
I have a class with an initializer-list constructor std::initializer_list<B>
. Is legal initialize it with an initializer list of objects of class D
, where D
is derived from 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 } };
}
If is not legal, is that ill-formed? or just undefined behavior?
I've tried that code in Visual Studio 2013 Update 1. It compiles, but when I run it, I can see (debugging) how:
I guess is a bug of the compiler (calling one destructor twice and missing the other one). But I'm not sure if that use of std::initializer_list is legal yet.
(Fixed the confusions about 'D' or 'A' name)
The conversion from std::initializer_list<D>
to std::initializer_list<B>
is valid...
And construct std::initializer_list<B>
with some D
is also valid...
But you will have object slicing
这篇关于是否合法使用initializer_list来初始化派生类型的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!