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));
}
};
然后
更改myfunction
使其接受optional_reference
然后检查它。
像下面这样包起来。
constexpr 常量静态自动 null_set();
void Myfunction(optional_wrapper ref)
{
我的函数(ref.value_or(null_set));
}
我有一个方法将 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));
}
};
然后
更改
myfunction
使其接受optional_reference
然后检查它。像下面这样包起来。
constexpr 常量静态自动 null_set(); void Myfunction(optional_wrapper ref) { 我的函数(ref.value_or(null_set)); }