Is legal use initializer_list to initialize an object with derived types?

家住魔仙堡 提交于 2019-12-14 04:08:49

问题


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:

  1. An object of class D is created for the first object D{1} (let call tempD1). D constructor is invoked and then the B constructor.
  2. The base of tempD1 is moved to a new B object (tmpB1): B move constructor is invoked.
  3. The same for the second object D{2} (tmpD2, tmpB2).
  4. Foo initializer-list constructor is invoked. All fine at this point.
  5. destructor of tmpB2 is invoked once.
  6. destructor of tmpD2 is invoked twice.
  7. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!