我如何保持聚合初始化,同时还添加自定义构造函数?



如果我没有在struct中定义构造函数,我可以通过选择一个特定的值来初始化它,像这样:

struct Foo {
int x, y;
};
Foo foo = {.y = 1};

但是如果我添加新的默认构造函数,那么我就失去了这个特性:

struct Bar {
int x, y;
Bar(int value) : x(value), y(value) {}
};
Bar bar1 = 1;
Bar bar2 = {.y = 2}; // error: a designator cannot be used with a non-aggregate type "Bar"

有可能两者兼得吗?

我尝试添加默认构造函数Bar () {},但它似乎也不起作用。

鱼和熊掌不可兼得。如果对象有构造函数,它就不再是聚合,并且只有聚合可以用指定的初始化器初始化。你不能使用构造函数来任意初始化聚合逻辑。 我们干杯了吗?不,因为有命名构造函数习语。它本质上只是一个静态成员函数,返回一个初始化的对象,并能够执行一些逻辑。此习语与聚合初始化兼容。
struct Foo {
int x, y;
static Foo filled_with(int value) {
return {.x = value, .y = value};
}
};
Foo foo = {.y = 1}; // Still an aggregate.
Foo foo2 = Foo::filled_with(2); // Custom logic

甚至没有任何复制或移动,因为c++ 17删除了这些可能性。foo2直接初始化

与ellipticaldoor写的类似:

struct FooBase {
int x = 0, y = 0;
};
struct Foo : FooBase {
Foo(int x_) : FooBase{.x = x_} { }
Foo(FooBase &&t) : FooBase{t} {}
};
Foo foo = {{.y = 1}};
Foo foo2{1};

到目前为止,这是我能找到的最接近的东西:

struct Vec2 {
int x, y;
};
struct Bar {
int x, y;
Bar(int value) : x(value), y(value) {}
Bar(Vec2 value) : x(value.x), y(value.y){};
};
Bar bar1 = 1;
Bar bar2 = {{.y = 2}};

但是需要使用双参数

您可以使用数据成员初始化器,使类型保持聚合:

struct Foo {
int x = 0, y = x;
};
Foo foo1 = {.y = 6};  // Foo{0, 6}
Foo foo2{7};          // Foo{7, 7}

(虽然不能从int隐式构造)

相关内容

  • 没有找到相关文章

最新更新