0

好吧,也许从标题不清楚我实际上在问什么。

我有一个带有初始化列表构造函数的类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 中尝试过该代码。它可以编译,但是当我运行它时,我可以看到(调试)如何:

  1. D为第一个对象D{1}(let call )创建一个类对象tempD1D构造函数被调用,然后是B构造函数。
  2. 的基础tempD1被移动到一个新B对象(tmpB1):B调用移动构造函数。
  3. 第二个对象D{2}( tmpD2, tmpB2) 也是如此。
  4. Foo初始化列表构造函数被调用。此时一切都很好。
  5. 的析构函数tmpB2被调用一次。
  6. 的析构函数tmpD2被调用两次
  7. 的析构函数tmpD1被调用一次。

我猜是编译器的一个错误(调用一个析构函数两次而错过了另一个)。但我不确定 std::initializer_list 的使用是否合法。

(修复了关于“D”或“A”名称的混淆)

4

1 回答 1

4

std::initializer_list<D>to的转换std::initializer_list<B>是无效的......但是std::initializer_list<B>用 some构造 aD是有效的(这就是这里发生的事情)......

但是你会有对象切片

于 2014-02-12T15:54:39.750 回答