简体   繁体   English

是否合法使用initializer_list初始化具有派生类型的对象?

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

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> . 我有一个带有初始化列表构造器std::initializer_list<B> Is legal initialize it with an initializer list of objects of class D , where D is derived from 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 } };
}

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: 我已经在Visual Studio 2013 Update 1中尝试过该代码。它可以编译,但是当我运行它时,我可以看到(调试)如何:

  1. An object of class D is created for the first object D{1} (let call tempD1 ). 为第一个对象D{1}创建类D的对象(调用tempD1 )。 D constructor is invoked and then the B constructor. 调用D构造函数,然后调用B构造函数。
  2. The base of tempD1 is moved to a new B object ( tmpB1 ): B move constructor is invoked. tempD1的基础移至新的B对象( tmpB1 ):调用B move构造函数。
  3. The same for the second object D{2} ( tmpD2 , tmpB2 ). 第二个对象D{2}tmpD2tmpB2 )相同。
  4. Foo initializer-list constructor is invoked. Foo初始化列表构造器被调用。 All fine at this point. 此时一切都很好。
  5. destructor of tmpB2 is invoked once. tmpB2析构tmpB2被调用一次。
  6. destructor of tmpD2 is invoked twice . tmpD2析构tmpD2被调用两次
  7. destructor of tmpD1 is invoked once. tmpD1析构tmpD1被调用一次。

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. 但是我不确定std :: initializer_list的使用是否合法。

(Fixed the confusions about 'D' or 'A' name) (解决了有关“ D”或“ A”名称的困惑)

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)... std::initializer_list<D>std::initializer_list<B>的转换无效...但是用一些D构造std::initializer_list<B>是有效的(这就是这里发生的情况)...

But you will have object slicing 但是你将有对象切片

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM