lundi 2 mai 2016

Avoid returning by-reference argument

Suppose I have a class Option:

template<typename T>
class Option {
public:
    Option() noexcept
    {}

    Option(T val) noexcept : val_(std::make_shared<T>(std::move(val)))
    {}

    const T & get() const
    {
        if (val_ == nullptr) {
            throw std::out_of_range("get on empty Option");
        }
        return *val_;
    }

    const T & getOrElse(const T &x) const
    {
        return val_ == nullptr ? x : *val_;
    }

private:
    std::shared_ptr<T> val_;
}

The argument passed to Option::getOrElse is the default value to return when this Option is empty:

Option<int> x;  // empty
int y = 123;
x.getOrElse(y);  // == 123

However, I think the following code is not safe:

Option<int> x;
x.getOrElse(123);  // reference to temporary variable!

A safer way would be to return by value from Option::getOrElse, but that would be wasteful when the Option is non-empty. Can I work around this somehow?

UPDATE: I'm thinking about perhaps overloading on the argument type (lvalue/rvalue) of getOrElse, but haven't figured out exactly how to do so.

Aucun commentaire:

Enregistrer un commentaire