首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++可选参考

C++可选参考
EN

Code Review用户
提问于 2020-03-25 14:53:12
回答 1查看 1.5K关注 0票数 4

下面是一个好的文章,用于C++中的可选引用类型。他们讨论std::optional<T&>,但由于没有编译,我已经做了自己的工作。

这种类型的目的之一是从函数签名中删除原始指针(在函数签名中不能单独使用引用),因为原始指针并不表示它将用于什么(变为拥有、删除、迭代、取消引用等)。

代码语言:javascript
运行
复制
#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(); }
};
EN

回答 1

Code Review用户

回答已采纳

发布于 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_valuenoexcept。为什么value_or接受一个rvalue引用?引入悬挂引用,如在opt.value_or(1)中?用一个无值引用代替。

布尔算子== (const & t) {返回data.value() == t;} bool运算符== (const std::nullopt_t&) {返回!data.has_value();}

我不确定这是不是正确的方法。第一个==比较值(如果没有值则抛出异常),而第二个==比较引用本身。您可以模仿std::optional的行为:

代码语言:javascript
运行
复制
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
  • ..。
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/239409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档