使用初始化列表初始化派生 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 中对对和元组所做的那样)。
我得到了一个 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 中对对和元组所做的那样)。