使用初始化列表初始化派生类对象

3

我有一个派生自struct Astruct B

struct A{
  int a;  
};

struct B : public A{
    int b;
};

有没有一种直接的方法来初始化一个类型为B的对象,而不需要提供构造函数,比如使用初始化列表?
更多信息:
我有两个结构体,用于在线程之间传递数据;第二个结构体保存了与第一个结构体相同的数据,另外还有一些同步变量。我可以将第一个结构体作为第二个结构体的数据成员,或者只是复制第二个结构体中的数据成员声明,以便轻松使用初始化列表;但我认为在这个特定的应用中,第二个结构体扩展第一个结构体会更加合理。
2个回答

3

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

#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)...)
    { }
};

这个解决方案并不简短,但它是通用的。对于那些有意义的特化,由于启用了SFINAE,B 的新构造函数仅存在于这些特化中,因此 B 的构造方式非常适用。

这里还有一个危险,即新构造函数应该有多明确。理想情况下,它应该与匹配的 A 构造函数一样明确,但从程序上检测起来有点困难(如在N4064中对于对和元组)。


0

你不能使用聚合初始化来初始化 B,因为根据[dcl.init.aggr]/ 1的规定,它不是一个聚合体:

聚合体是指没有用户提供构造函数(12.1),没有私有的或保护的非静态数据成员(Clause 11),没有基类(Clause 10),也没有虚函数(10.3)的数组或类(Clause 9)。

更新:Kerrek SB提供了使用模板构造函数的好方法,但如果你愿意,你可以为 B 添加相当简单的非模板构造函数:

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

并使用一个额外的花括号:

B b {{3}, 5};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接