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

C++ what is the idiomatic way to avoid pointers?

我有一个方法将 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 程序员只想更改函数以接受指针并在未找到 set 时传递 nullptr,但我觉得 C++ 现在都是关于避免指针的吗?..

您可以使用条件运算符:

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

虽然我认为没有惯用的方法。

如果您编写了一个辅助函数来在映射中找到一个集合,那么您可以 return 在您没有找到任何东西的情况下引用一个特殊的空集合:

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"));

可能是手写的 optional_reference 可以引用 nullptr 但在取消引用时会 throw 并且没有额外的 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));
    }
};

然后

  1. 更改myfunction使其接受optional_reference然后检查它。

  2. 像下面这样包起来。

    constexpr 常量静态自动 null_set(); void Myfunction(optional_wrapper ref) { 我的函数(ref.value_or(null_set)); }