1

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

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");
    }();
};

但我更愿意使用编译时错误来执行此操作。有没有办法做到这一点?如有必要,我可以更改boolSomeWrapper<bool>,只要我可以像初始化SomeWrapper<T>一样进行初始化T,但没有默认初始化程序。

4

2 回答 2

2

您澄清说这是关于任意类,而不是原始类型。对于具有任意构造函数的任意类:只需删除构造函数,但显式删除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根据需要进行专业化。没有那么多原始类型需要处理。

于 2019-11-02T00:46:30.927 回答
1

感谢 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; }
};

演示

于 2019-11-02T01:18:20.480 回答