c++ - 合法使用 initializer_list 来初始化具有派生类型的对象吗?

标签 c++ inheritance c++11 initializer-list object-slicing

嗯,也许从标题看不清楚我到底在问什么。

我有一个带有初始化列表构造函数的类 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} (让我们调用 tempD1 )。 D调用构造函数,然后调用 B构造函数。
  2. 基地tempD1已移至新的 B对象(tmpB1):B移动构造函数被调用。
  3. 第二个对象相同D{2} ( tmpD2 , tmpB2 )。
  4. Foo初始化列表构造函数被调用。此时一切都很好。
  5. tmpB2 的析构函数被调用一次。
  6. tmpD2 的析构函数被调用两次
  7. tmpD1 的析构函数被调用一次。

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

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

最佳答案

来自 std::initializer_list<D> 的转换至 std::initializer_list<B>无效... 但是构建一个 std::initializer_list<B>与一些D是有效的(这就是这里发生的事情)...

但是你会得到object slicing

关于c++ - 合法使用 initializer_list 来初始化具有派生类型的对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21731601/

相关文章:

c++ - 如何使用 Linux getrandom 系统调用生成一个范围内的随机数?

c++ - 将派生类存储到 vector C++

.net - 从子应用程序卸载 web.config 文件的一部分

c++ - 如何将这个运行时高效的函数变成一个 constexpr?

c++ - OpenGL 投影/矩阵混淆

c++ - 推力与 cublas 的性能

c++ - 何时使用 move 构造函数/赋值

python类属性继承

c++ - 右值引用和文字

c++ - std::thread 无法在 linux eclipse 上工作