下面是一个好的文章,用于C++中的可选引用类型。他们讨论std::optional<T&>,但由于没有编译,我已经做了自己的工作。
这种类型的目的之一是从函数签名中删除原始指针(在函数签名中不能单独使用引用),因为原始指针并不表示它将用于什么(变为拥有、删除、迭代、取消引用等)。
#include <functional>
#include <optional>
template<typename T>
/** @brief An optional refference **/
class opt_ref {
    using std_opt_ref = std::optional<std::reference_wrapper<T>>;
    std_opt_ref data = std::nullopt;
public:
    using type = typename std::reference_wrapper<T>::type;
    /** public member functions **/
    T& get() { return data.value().get(); }
    const T& get() const { return data.value().get(); }
    bool has_value() const { return data.has_value(); }
    T& value_or(T&& other) const { return data.value_or(other); }
    /** constructors **/
    opt_ref() {}
    opt_ref(T& source) : data(source) {}
    opt_ref& operator = (T&& other) { data.value().get() = other; return *this; }
    /** comparisons **/
    bool operator == (const T& t) { return data.value() == t; }
    bool operator == (const std::nullopt_t&) {return !data.has_value(); }
    /** implicit conversion **/
    operator T&() { return data.value().get(); }
    operator const T&() const { return data.value().get(); }
    operator std::reference_wrapper<T>() { return data.value(); }
    operator const std::reference_wrapper<T>() const { return data.value(); }
};发布于 2020-03-26 02:15:11
引用与指针有两种不同之处:
您不能总是用optional来模仿第一个项目--例如,没有通用的方法来让opt.f()调用opt.value().f()。您仍然需要使用其他一些语法,如opt->value()。因此,我的建议是简单地将opt_ref<T>视为一个不可变的可空指针,它不拥有所引用的对象--不要遵循std::reference_wrapper。
使用type =type type std::reference_wrapper::type;
typename std::reference_wrapper::type就是T。另外,标准术语是value_type。
T& get() {返回data.value().get();} const T& get() const {返回data.value().get();} bool has_value() const {返回data.has_value();} T& value_or(T&其他) const {返回data.value_or(其他)};
has_value是noexcept。为什么value_or接受一个rvalue引用?引入悬挂引用,如在opt.value_or(1)中?用一个无值引用代替。
布尔算子== (const & t) {返回data.value() == t;} bool运算符== (const std::nullopt_t&) {返回!data.has_value();}
我不确定这是不是正确的方法。第一个==比较值(如果没有值则抛出异常),而第二个==比较引用本身。您可以模仿std::optional的行为:
bool operator==(const opt_ref<T>& a, const opt_ref<T>& 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();
    }
}运算符T&() {返回data.value().get();}运算符const T&() const {返回data.value().get();}运算符std::reference_wrapper() {返回data.value();}运算符const std::reference_wrapper() const {返回data.value();}
如前所述:您确定要这样做(特别是对reference_wrapper的隐式转换)吗?
考虑:
operator*和operator->;explicit operator bool;has_value;https://codereview.stackexchange.com/questions/239409
复制相似问题