Boost logo

Boost :

From: Dave Gomboc (dave_at_[hidden])
Date: 2003-08-29 18:12:48


> Right now I am questioning whether the
> pointer-like semantics is worth it to me. I would probably prefer that
> clients type more to test whether a value is initialized so that they
> can type less to call a function that takes an optional as a parameter
> when they have a value to pass in. Sorry if this has already been
> covered, but here my question is: Have you experimented with a variant
> of optional that drops the pointer-like semantics, allowing implicit
> construction and disallowing implicit safe-bool conversion, and if so
> what did you learn that made you favor the current set of tradeoffs?

I've never been comfortable with the pointer-like semantics of optional. If
you don't need an industrial-strength solution like Fernando's, perhaps
something simple like the below would be sufficient? (Also, feel free to
suggest improvements.)

Dave

    template <typename T>
    class nilable {

    public:

        nilable(void) : nil_(true) {};
        nilable(const T & value) : value_(value), nil_(false) {};

        // rely on default destructor, copy constructor, and assignment
operator

        bool nil(void) const { return nil_; };

        operator T(void) const {
            if (nil_) boost::throw_exception(std::bad_cast());
            return value_;
        };

        const T & unsafe_reference(void) const { return value_; };
        T & unsafe_reference(void) { return value_; };

        const T unsafe_value(void) const { return value_; };
        T unsafe_value(void) { return value_; };

    private:

        T value_;
        bool nil_;

    };

    template <typename T>
    bool
    operator! (const nilable<T> & a) {
        return (a.nil() || !a.unsafe_reference());
    };

    template <typename T>
    bool
    operator< (const nilable<T> & a, const nilable<T> & b) {
        if (b.nil()) return false;
        if (a.nil()) return true;
        return (a.unsafe_reference() < b.unsafe_reference());
    };

    template <typename T>
    std::ostream &
    operator<< (std::ostream & out, const nilable<T> & value) {
        if (value.nil()) {
            out << "nil";
        } else {
            out << value.unsafe_reference();
        };
    };

    // TODO: add input from std::istreams.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk