如何防止boost :: optional <T>被错误地构造为0?

Gur*_*pof 8 c++ boost boost-optional

boost::optional<T>(1.51)提供了一种构建对我的用户非常危险的对象的方法,我想阻止它.假设我有自己的整数类,我想传递一个可选的这样的整数并将其存储在某个类中:

class myint {
public:
    int m_a;
    myint (int r_a) : m_a(r_a) {
    }
};

struct myclass {
    boost::optional<myint> content;
    myclass (const boost::optional<myint>& arg) : content(arg) {
    }
};
Run Code Online (Sandbox Code Playgroud)

现在,这是用户如何使用该类:

myclass(myint(13));            //correct use
myclass(boost::none);          //correct use
myclass(myint(0));             //correct use
myclass(0);                    //INCORRECT use, this easy typo
                               //equates boost::none which
                               //is not what the user meant
Run Code Online (Sandbox Code Playgroud)

我想了解这里发生了什么,并防止这种行为.


有趣的是,

myclass(1);              //does not compile
Run Code Online (Sandbox Code Playgroud)

boost::none对于我的领域来说,这完全是一个有效的价值,但是boost::none当用户试图输入时,有一个偷偷摸摸的东西0是极其误导和危险的.

意图可能有点隐藏,因为我并没有真正推出一个myint课程而且我真的class myclass没有任何目的.无论如何,我需要向函数发送10个左右的可选ints,并且重复数据删除不起作用.(你可以想象我问你的年龄,身高和财富,还有三个特殊按钮可以检查你是否不想回答问题)


我发布了一个似乎在下面工作的答案(根据Mooing的Duck&Ilonesmiz建议,但更轻).不过,我很高兴听到有关它的评论.

Gur*_*pof 1

这段代码(受 Ilonesmiz 启发)似乎可以很好地完成工作,并且比 Mooing Duck 的方法要轻一些,但仍然使用了神奇的模板技巧。

struct myprotectedclass {
    boost::optional<myint> content;

    template <class T>
    myprotectedclass(const T& a) :content(boost::optional<myint>(a)) {}


};
Run Code Online (Sandbox Code Playgroud)

这是证明。
当 C++ 看到 时0,它会认为“嗯,这可能是一个 int,但它可能是一个指向某个东西的指针!” (仅适用于0,没有其他数字)但是如果将其传递0给函数,它必须决定类型,因此它选择默认值int。而在原始版本中, a被传递给需要 a或指针(是指针)0的函数。不是 myint,但它可以是一个指针,所以它选择了那个。myintboost::none_t0

  • 当 C++ 看到 ‘0’ 时,它会认为“嗯,这可能是一个 ‘int’,但它可能是一个指向某个东西的指针!” (仅适用于“0”,没有其他数字)但是如果将“0”传递给函数,它必须决定类型,因此它选择默认值“int”。而在原始版本中,您将其传递给需要“myint”或指针的函数(“boost::none_t”是一个指针)。`0` 不是 `myint`,但它可以是一个指针,所以它选择了那个。 (2认同)