【发布时间】:2019-11-02 00:29:00
【问题描述】:
我创建了一个 options 结构体,旨在通过指定的初始化程序使用:
struct FooOptions {
bool enableReticulation;
};
void Foo(FooOptions&& opts);
Foo(FooOptions{.enableReticulation = true});
不幸的是,因为bool 有一个默认构造函数,这样做也是有效的:
Foo(FooOptions{});
但我不想要这个;我希望 Foo 的用户明确决定是否启用网状结构。我可以通过这种方式通过运行时错误来实现这一点:
struct FooOptions {
bool enableReticulation = []() -> bool {
assert(false, "No value provided for enableReticulation");
}();
};
但我更愿意使用编译时错误来执行此操作。有没有办法做到这一点?如有必要,我可以将bool 更改为SomeWrapper<bool>,只要我可以像T 一样初始化SomeWrapper<T>,但没有默认初始化程序。
【问题讨论】:
-
当然,这正是您执行此操作的方法,方法是使用带有非默认构造函数的包装器类型。正如让-卢克·皮卡德上尉所说:做到这一点。
-
问题是我希望
SomeWrapper<T>可以以所有T可以构造的方式构造,except 默认构造。对于像bool这样的简单类型,这很容易,但是如果我有SomeWrapper<std::vector<int>>,我希望能够使用std::initializer_list<int>、一对迭代器、一个分配器以及std::vector的所有其他方式进行初始化已初始化。 -
您可以对第二个参数使用可变参数模板并完美转发所有参数
-
所以?要么委托构造函数,并明确地
delete默认构造函数,要么使用具有至少一个参数的转发构造函数。 -
我已经尝试了一些没有成功的事情:(我要么得到多个重载解析为相同的类型,这是无效的,要么我最终得到的包装器仍然是默认可构造的,用于空参数包。
标签: c++ initialization designated-initializer