I've got an optional-like class (I can't use optional since it's in C++17). It contains a (possible) value along with a flag indicating if it's valid. I've got an explicit bool operator and a conversion operator to get the value out. The problem is, sometimes C++ will choose the bool operator in an explicitly bool context (an if statement), and other times it won't. Can anyone help me understand this behavior:
#include <algorithm>
#include <stdexcept>
template <typename T>
struct maybe {
    maybe()        : valid_(false) {}
    maybe(T value) : valid_(true)  { new (&value_) T(value); }
    operator T&&() {
        return std::move(value());
    }
    explicit operator bool() const {
        return valid_;
    }
    T& value() {
        if (!valid_) {
            throw std::runtime_error("boom");
        }
        return value_;
    }
private:
    union {
        T value_;
    };
    bool valid_;
};
int main() {
    // fine, uses operator bool()
    maybe<std::pair<int,int>> m0;
    if (m0) {
        std::pair<int,int> p = m0;
        (void)p;
    }
    // throws error, uses operator T&&()
    maybe<double> m1;
    if (m1) {
        double p = m1;
        (void)p;
    }
}   
 
     
     
    