当使用指定的初始值设定项时,我可以强制用户为成员提供值吗

Can I force a user to provide a value for a member when using designated initializers?

本文关键字:我可以 用户 成员      更新时间:2023-10-16

我创建了一个选项结构,旨在通过指定的初始值设定项使用:

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>,但没有默认的初始化器。

您澄清了这是关于任意类的,而不是基元类型。对于任意类,使用任意构造函数:只需删除构造函数,但显式地delete默认构造函数:

template<typename T> class SomeWrapper : public T {
SomeWrapper()=delete;
using T::T;
};

然后:

#include <vector>
foo F{ {1,2} }; // Works, initializes the vector with {1,2}
foo G{}; // Fails

对于基元类型,这可能无法正常工作。只需根据需要专门化SomeWrapper即可。没有那么多原始类型需要处理。

处理类和非类类型的方法,感谢SFINAE:

template<typename T, typename Enabler = void> class TWrapper;
template<typename T>
class TWrapper<T, std::enable_if_t<std::is_class<T>::value>> : public T {
public:
TWrapper()=delete;
using T::T;
};
template<typename T>
class TWrapper<T, std::enable_if_t<!std::is_class<T>::value>>
{
public:
TWrapper()=delete;
T value;
TWrapper(T arg) : value(arg) {}
operator T() const { return value; }
};

演示