boost::optional<T> (1.51) provides a way of constructing objects that is very dangerous for my users and that I'd like to prevent. Let's say I have my own integer class and I want to pass an optional such integer and store it in some class:
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) {
    }
};
and now, here's how users would use the class:
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
I'd like to understand what is going on here and prevent this behaviour.
Interestingly,
myclass(1);              //does not compile
boost::none is totally a valid value for my field, but having a boost::none sneak-up when the user is trying to type in a 0 is horrendously misleading and dangerous.
The intent might be a bit hidden since I'm not really rolling out a myint class and I don't really have a class myclass that serves little to no purpose. Anyways I need to send 10 or so optional ints to a function and deduping wouldn't work. (you can imagine I asked you for your age, your height and your wealth and that there's three special buttons to check if you don't want to answer a question)
I've posted an answer that seems to work below (built from Mooing's Duck & Ilonesmiz suggestion, but lighter). I'm happy to hear comments about it, though.
Do not let the constructor take a boost::optional I would do something like this instead.
struct myclass {
    boost::optional<myint> content;
    myclass () = default;
    explicit myclass(const myint& int_):content(int_){}
};
However when I am thinking about it I am not completely clear on what you are trying to achieve and what you want to avoid happening. What is the purpose of the optional member? 
This is uglier than I like, but it seems to address your concerns.  It works by forwarding the argument given to myclass perfectly to a pair of functions that take either an int or a boost::none_t, bypassing the implicit user-defined constructor.  This works because 0 matches int better than boost::none_t, and an implicit user-defined constructor is the worst match.
class myint {
public:
    int m_a;
    myint (int r_a) : m_a(r_a) {}
};    
boost::optional<myint> myintctor(int arg) {return myint(arg);}
boost::optional<myint> myintctor(boost::none_t arg) {return arg;}
struct myclass {
    boost::optional<myint> content0;
    boost::optional<myint> content1;
    boost::optional<myint> content2;
    template<class T0, class T1, class T2>
    myclass(const T0& a0, const T1& a1, const T2& a2) 
    :content0(myintctor(a0)), content1(myintctor(a1)), content2(myintctor(a2))
    {}
};
Proof of concept.  Modern compilers ought to be smart enough to elide the copy, but that shouldn't matter for an int.
I guess the problem is only meaningful for optional int. One solution could be to provide two constructors:
myclass() : content(boost::none) {}
myclass(myint input) : content(input) {}
It's true that you lose a bit the advantage of boost::optional...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With