问题
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:
- 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.
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)
回答1:
The conversion from std::initializer_list<D>
to std::initializer_list<B>
is not valid...
But construct a std::initializer_list<B>
with some D
is valid (and it is what happens here)...
But you will have object slicing
来源:https://stackoverflow.com/questions/21731601/is-legal-use-initializer-list-to-initialize-an-object-with-derived-types