I omitted all free operators but the equality comparisons ones because of verbosity. I am glad about any comments and improvements.MotivationI know that optional references are equivalent to pointers and their implementation is just such a wrapper. But I believe they make sense in some circumstances and please correct me if I am wrong.While implementing and using my interval map I needed to return an optional reference in one of its accessor methods, namely operator[](Key). The idea is to get a reference to a stored value or nothing. Thus I did it there with an std::optional<std::reference_wrapper<const T>>. Following this pattern of optional refs led to complications when I tried accessing an std::optional<std::reference_wrapper<T>> at some other point of time. I couldn't write something like thisint a = 0;std::optional<std::reference_wrapper<int>> opt{a};*opt = 42;assert(a == 42);but instead one has to explicitly unwrap the reference_wrapper like thisopt.value().get() = 42;assert(a == 42);oropt->get() = 42assert(a == 42);And my motivation for optional_ref was born.Source codeHere is the complete source code on wandbox.optional_ref.hpp#include <type_traits>#include <cassert>#include <stdexcept>#include range/v3/utility/concepts.hppnamespace fub{struct bad_optional_access : std::runtime_error {  using runtime_error::runtime_error;};template <typename T>  class optional_ref {  public:    using element_type = T;    using reference = element_type&;    using pointer = element_type*;    // CONSTRUCTORS    optional_ref() = default;    template <typename S,         CONCEPT_REQUIRES_(ranges::ConvertibleTo<S*, T*>())>      constexpr optional_ref(const optional_ref<S>& other)      noexcept      : m_pointer{other.get_pointer()} {}    constexpr optional_ref(reference element)    noexcept    : m_pointer{std::addressof(element)} {}    // ASSIGNMENT    template <typename S,         CONCEPT_REQUIRES_(ranges::ConvertibleTo<S*, T*>())>      constexpr optional_ref&      operator=(const optional_ref<S>& other)      noexcept      {        m_pointer = other.get_pointer();      }    // DESTRUCTOR    ~optional_ref() = default;    // SWAP    void swap(optional_ref& other)    noexcept    {      swap(m_pointer, other.m_pointer);    }    // OBSERVERS    constexpr bool    has_value() const    noexcept    { return m_pointer != nullptr; }    constexpr pointer    get_pointer() const    noexcept    { return m_pointer; }    constexpr reference    value() const    {      if (!has_value()) {        throw bad_optional_access(          fub::optional_ref::value: optional_ref is empty.        );      }      return *get_pointer();    }    template <typename U,        CONCEPT_REQUIRES_(ranges::ConvertibleTo<U, reference>())>      constexpr reference      value_or(U&& alternative) const      noexcept      {        if (has_value()) {          return *get_pointer();        }        return alternative;      }    constexpr pointer    operator->() const    noexcept    {      assert(has_value());      return get_pointer();    }    constexpr reference    operator*() const    noexcept    {      assert(has_value());      return *get_pointer();    }    constexpr operator    bool() const    noexcept    { return has_value(); }    // MODIFIERS    void reset()    noexcept    {      m_pointer = nullptr;    }  private:    pointer m_pointer{nullptr};  };// EQUALITY COMPARISONtemplate <typename T, typename S,    CONCEPT_REQUIRES_(ranges::EqualityComparable<T, S>())>  bool operator==(optional_ref<T> left, optional_ref<S> right)  noexcept(noexcept(*left == *right))  {    return (!left && !right) || (left && right && *left == *right);  }template <typename T, typename S,    CONCEPT_REQUIRES_(ranges::EqualityComparable<T, S>())>  bool operator!=(optional_ref<T> left, optional_ref<S> right)  noexcept(noexcept(left == right))  {    return !(left == right);  }// EQUALITY COMPARISON WITH Ttemplate <typename T, typename S,    CONCEPT_REQUIRES_(ranges::EqualityComparable<T, S>())>  bool operator==(optional_ref<T> left, const S& right)  noexcept(noexcept(*left == right))  {    return left && *left == right;  }template <typename T, typename S,    CONCEPT_REQUIRES_(ranges::EqualityComparable<T, S>())>  bool operator==(const T& left, optional_ref<S> right)  noexcept(noexcept(left == *right))  {    return right && left == *right;  }template <typename T, typename S,    CONCEPT_REQUIRES_(ranges::EqualityComparable<T, S>())>  bool operator!=(optional_ref<T> left, const S& right)  noexcept(noexcept(left == right))  {    return !(left == right);  }template <typename T, typename S,    CONCEPT_REQUIRES_(ranges::EqualityComparable<T, S>())>  bool operator!=(const T& left, optional_ref<S> right)  noexcept(noexcept(left == right))  {    return !(left == right);  }Some tests (see also on wandbox)TEST_CASE(optional refs are regular types){  REQUIRE(ranges::Regular<optional_ref<int>>());  REQUIRE(ranges::Regular<optional_ref<std::unique_ptr<int>>>());  REQUIRE(ranges::Regular<optional_ref<char[30]>>());  REQUIRE(ranges::Regular<optional_ref<double[]>>());}TEST_CASE(compare const int refs with int refs){  int a = 42;  int b = 24;  const int c = 42;  optional_ref<int> ref_a = a;  optional_ref<const int> ref_x;  REQUIRE(!ref_x);  REQUIRE(!ref_x.has_value());  REQUIRE(ref_a != ref_x);  ref_x = c;  REQUIRE(ref_a == ref_x);  REQUIRE(ref_a.get_pointer() != ref_x.get_pointer());  ref_x = b;  REQUIRE(ref_a != ref_x);  ref_x = a;  REQUIRE(ref_a.get_pointer() == ref_x.get_pointer());}TEST_CASE(Arrow operator works with objects){  struct A {    int foo;    char bar;  };  A a{4, '2'};  optional_ref<A> ref{a};  REQUIRE(ref->foo == 4);  REQUIRE(ref->bar == '2');}void access_throws(optional_ref<const int> ref){  REQUIRE_THROWS_AS(ref.value(), bad_optional_access);}TEST_CASE(throw error on using empty optional_ref){  auto ref = optional_ref<int>{};  access_throws(ref);}TEST_CASE(assign reference){  int a = 0;  optional_ref<int> ref{a};  REQUIRE(ref == 0);  *ref = 42;  REQUIRE(ref == 42);}
An optional_ref
c++;c++14;pointers;optional