C++ C++;避免指针的惯用方法是什么?

C++ C++;避免指针的惯用方法是什么?,c++,coding-style,C++,Coding Style,我有一个方法,将const ref作为一个集合。我想打电话,然后m.b.传一套给它。如果我有。所以首先我看看我是否有一套: const auto& it = mapOfSets.find("token"); if (it != std::end(mapOfSets)) { myFunction(it.second); } else { MySetType emptySet; myFunction(emptySet); } 这样做的惯用方法是什么?我不喜欢上面的内容,因为对m

我有一个方法,将const ref作为一个集合。我想打电话,然后m.b.传一套给它。如果我有。所以首先我看看我是否有一套:

const auto& it = mapOfSets.find("token");
if (it != std::end(mapOfSets)) {
  myFunction(it.second);
} else {
  MySetType emptySet;
  myFunction(emptySet);
}
这样做的惯用方法是什么?我不喜欢上面的内容,因为对myFunction的调用重复了两次,并且还有一些其他参数,因此存在一些不必要的代码重复


< >我的C程序员只想改变函数接受指针,如果没有找到NulLPTR,但我觉得C++现在都是为了避免指针……< /p> < p>可以使用条件运算符:

myFunction(it != mapOfSets.end() ? it->second : MySetType{});

不过,我认为没有惯用的方法。

如果您编写了一个helper函数来查找映射中的集合,那么您可以在没有找到任何内容的情况下返回对特殊空集的引用:

const MySetType& find(const MyMapType& mapOfSets, const std::string& key) {
    auto it = mapOfSets.find(key);
    if (it != std::end(mapOfSets)) {
        return it->second;
    }
    static const MySetType emptySet;
    return emptySet;
}
那么您的调用代码就是:

myFunction(find(mapOfSets, "token"));

可能是一个手写的
可选\u引用
,可以引用
nullptr
,但在取消引用时将
抛出
,并且没有额外的
bool

#include <stdexcept>
#include <memory>

class null_access_exception: public std::logic_error
{
    using base = std::logic_error;
public:
    null_access_exception():
        base("Try to dereference null optional_reference!")
    {}
};

template <class Ptr_t>
class optional_reference
{
    using self = optional_reference;
    using reference = decltype(*std::declval<Ptr_t>());
    Ptr_t ptr = nullptr;

public:
    optional_reference() = default;
    optional_reference(const self&) = default;

    self& operator = (const self&) = delete;

    template <class U>
    constexpr optional_reference(U &&obj) noexcept: 
        ptr(std::addressof(obj))
    {}

    constexpr explicit operator bool() const noexcept
    { return has_value(); }

    constexpr bool has_value() const noexcept
    { return ptr != nullptr; }

    constexpr auto& value() const
    {
        if (!has_value())
            throw null_access_exception();

        return *ptr;
    }

    template <class U>
    constexpr auto& value_or(U &&obj) const noexcept
    {
        if (has_value())
            return *ptr;
        else
            return reference(std::forward<U>(obj));
    }
};
#包括
#包括
类null\u访问\u异常:公共std::逻辑\u错误
{
使用base=std::logic\u错误;
公众:
null\u访问\u异常():
base(“尝试取消对空可选_引用的引用!”)
{}
};
样板
类可选参考
{
使用self=可选_参考;
使用reference=decltype(*std::declval());
Ptr_t Ptr=nullptr;
公众:
可选_reference()=默认值;
可选_引用(const self&)=默认值;
self&运算符=(const self&)=删除;
样板
constexpr可选参考(U&&obj)无例外:
ptr(std::addressof(obj))
{}
constexpr显式运算符bool()const noexcept
{return具有_值();}
constexpr bool具有_值()const noexcept
{return ptr!=nullptr;}
constexpr auto&value()常量
{
如果(!具有_值())
抛出null_访问_异常();
返回*ptr;
}
样板
constexpr auto&value_或(U&obj)const noexcept
{
if(具有_值())
返回*ptr;
其他的
返回引用(std::forward(obj));
}
};
然后

  • 更改
    myfunction
    ,使其接受
    可选\u参考
    ,然后进行检查

  • 像下面一样把它包起来

    constexpr const static auto null_set(); void Myfunction(可选的包装器参考) { myfunction(ref.value_或(null_集)); }


  • it.second
    的类型是
    MySetType
    ,对吗?是的,希望它是关于避免原始指针的。像使用引用一样使用指针仍然可以。您可以创建一个返回
    可选
    的助手进行查找,并使用其
    值\u或
    函数。但是,如果没有对引用的本机支持,则会很尴尬。@NathanOliver有些人还建议避免使用原始的非拥有指针,因为在阅读作者知道并遵循建议避免使用原始指针的代码时,这通常不是一个安全的假设。至少这是干的,这很难看,但我喜欢。