当存在其他构造函数时,如何强制创建默认序列构造函数
How to force creation of default sequence constructor when other constructors are present?
从C 11开始,我们拥有此出色的功能,它使我们能够避免为所有小型类创建显式构造函数:
class A
{
public:
A() = default;
A(int x, int y) : x(x), y(y) {} // bloat
int x = 0, y = 0;
};
..
A a(1,2);
所以我们现在可以这样写:
class A
{
public:
int x = 0, y = 0;
};
..
A a{1,2}; // using the sequence constructor created by the compiler, great
出现的问题是,当我还有其他要使用的构造函数时,例如:
class A
{
public:
A() = default;
A(Deserialiser& input) : a(input.load<int>()), b(input.load<int>()) {}
int x = 0, y = 0;
};
...
A a{1, 2}; // It doesn't work now, as there is another constructor explicitly specified
问题是,如何强制编译器创建默认序列构造函数?
第二个示例的区别在于您正在做汇总初始化。
使用第一个和第三个示例,不再可能进行汇总初始化(因为该类具有用户定义的构造函数)。
使用第一个示例,然后称为两个题目的构造函数。使用第三个示例,找不到合适的构造函数,您将遇到错误。
注意:在第二个示例中,在C 11中也无法进行汇总初始化,因为C 11不允许非静态成员被初始化。在C 14中取消了该限制。(有关更多信息,请参见上面的链接参考。)
如果命名构造函数,则删除所有其他自动生成名称。
通过命名A(Deserialiser&)
,您丢失了自动生成的A(int, int)
在表达构造函数的路上将是:
class A
{
public:
A() : A(0, 0) {} // <- set default values here
A(int x, int y) : x(x), y(y) {}
A(Deserialiser& input) : x(input.load<int>()), y(input.load<int>()) {}
int x, y;
};
保留汇总初始化的一种方法是将序列化与对象本身分离。
template<class Type> struct type_tag {};
class A
{
public:
A() = default;
int x = 0, y = 0;
};
auto deserialise(Deserialiser& input, type_tag<A>)
{
return A { input.load<int>(), input.load<int>() };
}
只要您不提供任何类的构造函数,编译器自动生成默认构造函数。但是,一旦您提供了最低的构造函数,那么编译器即使没有更多默认构造函数也不会提供任何构造函数。
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 初始化具有非默认构造函数的std::数组项的更好方法
- 具有默认模板类型的默认构造函数的类型推导
- 如何使用非默认构造函数实例化模板化类
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 声明没有默认构造函数的字段
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 没有默认构造函数作为模板参数的自定义比较器
- C++17 没有默认构造函数的地图放置(私有默认构造函数)
- 使用移动调用对等构造函数unique_ptr默认构造函数
- C++复制构造函数和默认构造函数
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 构造函数默认公共和私有变量
- 类模板构造函数默认参数
- 构造函数默认参数
- C++模板构造函数默认参数
- 在c++中设置构造函数默认值
- c++构造函数默认参数
- C++构造函数默认值头文件