使用初始化列表初始化派生 class 的对象

Initializing object of derived class using initializer-list

我得到了一个 struct B 派生自 struct A

struct A{
  int a;  
};

struct B : public A{
    int b;
};

有没有直接的方法来初始化 B 类型的对象而不提供构造函数,比方说使用初始化列表?

更多见识:

我有两个 struct 用于在线程之间传递数据;第二个保存与第一个相同的数据,增加了一些同步变量。我可以使第一个 struct 成为第二个的数据成员,或者只是复制第二个 struct 中数据成员的声明,以便轻松使用初始化列表;但我认为 在这个特定的应用程序中 第二个 struct 扩展第一个

在逻辑上更正确

您不能对 B 使用聚合初始化,因为它不是聚合,根据 [dcl.init.aggr]/1:

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

更新:Kerrek SB 使用模板构造函数提供了一个很好的解决方案,但如果您愿意,您可以为 B 添加非常简单的非模板构造函数:

struct B : public A{
    int b;
    B(const A& a_, int b_) : A(a_), b(b_) {}
};

并与一对额外的牙套一起使用:

B b {{3}, 5};

没有一个非常简洁的解决方案,但至少一个解决方案:

#include <type_traits>
#include <utility>

struct B : A
{
    int b;

    template <typename ...Args,
              typename = typename std::enable_if<
                             std::is_constructible<A, Args&&...>::value>
    B(int x, Args &&... args)
    : b(x), A(std::forward<Args>(args)...)
    { }
};

这个解决方案并不十分简短,但它是通用的。由于 enable-if SFINAE,B 的新构造函数仅存在于那些有意义的专业化中,因此 B 完全可以构造。

这里还有一个我没有解决的危险,即 explicit 新构造函数应该如何。理想情况下,它应该与匹配的 A 构造函数一样明确,但这有点难以以编程方式检测(如 N4064 中对对和元组所做的那样)。