C++ Optional Reference Here is a good article on an optional reference type in C++. They discuss std::optional&lt;T&amp;&gt;, but as that doesn't compile I have made my own.

One purpose of this type is to remove raw pointers from function signatures (where references alone cannot be used), as a raw pointer does not convey any indication of what it will be used for (become owned, deleted, iterated, dereferenced, etc).

#include &lt;functional&gt;
#include &lt;optional&gt;

template&lt;typename T&gt;
/** @brief An optional refference **/
class opt_ref {
    using std_opt_ref = std::optional&lt;std::reference_wrapper&lt;T&gt;&gt;;
    std_opt_ref data = std::nullopt;
public:
    using type = typename std::reference_wrapper&lt;T&gt;::type;

    /** public member functions **/

    T&amp; get() { return data.value().get(); }
    const T&amp; get() const { return data.value().get(); }
    bool has_value() const { return data.has_value(); }
    T&amp; value_or(T&amp;&amp; other) const { return data.value_or(other); }

    /** constructors **/

    opt_ref() {}
    opt_ref(T&amp; source) : data(source) {}
    opt_ref&amp; operator = (T&amp;&amp; other) { data.value().get() = other; return *this; }

    /** comparisons **/

    bool operator == (const T&amp; t) { return data.value() == t; }
    bool operator == (const std::nullopt_t&amp;) {return !data.has_value(); }

    /** implicit conversion **/

    operator T&amp;() { return data.value().get(); }
    operator const T&amp;() const { return data.value().get(); }
    operator std::reference_wrapper&lt;T&gt;() { return data.value(); }
    operator const std::reference_wrapper&lt;T&gt;() const { return data.value(); }
};
Design

References are different from pointers in two ways:


they are designed to be aliases to the objects they refer to, so syntactically they are treated with special care;
they cannot be rebound.


You cannot always emulate the first bullet with an optional &mdash; for example, there's no general way to make opt.f() call opt.value().f().  You still have to resort to some other syntax like opt-&gt;value().  Therefore, my advice is to simply treat opt_ref&lt;T&gt; like an immutable nullable pointer that does not own the referred-to object &mdash; don't follow std::reference_wrapper.

Code Review


using type = typename std::reference_wrapper&lt;T&gt;::type;



typename std::reference_wrapper&lt;T&gt;::type is just T.  Also, the standard terminology is value_type.


T&amp; get() { return data.value().get(); }
const T&amp; get() const { return data.value().get(); }
bool has_value() const { return data.has_value(); }
T&amp; value_or(T&amp;&amp; other) const { return data.value_or(other); }



has_value is noexcept.  Why does value_or take an rvalue reference?  To introduce dangling references as in opt.value_or(1)?  Take an lvalue reference instead.


bool operator == (const T&amp; t) { return data.value() == t; }
bool operator == (const std::nullopt_t&amp;) {return !data.has_value(); }



I'm not sure this is the right approach.  The first == compares values (and throws an exception if there is no value), whereas the second == compares the references themselves.  You can imitate the behavior of std::optional:

bool operator==(const opt_ref&lt;T&gt;&amp; a, const opt_ref&lt;T&gt;&amp; b)
{
    if (a.has_value() != b.has_value()) {
        return false;
    } else if (!a.has_value()) { // and !b.has_value()
        return true;
    } else {
        return a.get() == b.get();
    }
}



operator T&amp;() { return data.value().get(); }
operator const T&amp;() const { return data.value().get(); }
operator std::reference_wrapper&lt;T&gt;() { return data.value(); }
operator const std::reference_wrapper&lt;T&gt;() const { return data.value(); }



As I said before: are you sure you want this (especially the implicit conversions to reference_wrapper)?

Other functionalities

Consider:


operator* and operator-&gt;;
explicit operator bool;
has_value;
...