如何在<T>没有 if 语句的情况下返回可选?
How to return an optional<T> without an if statement?
假设我有一个函数,它查找并返回向量的最小元素。如果向量为空,则应返回一个空的可选对象。有没有办法让我使用 optional<T>
构造函数来避免使用 if 语句或三元运算符?
使用 if 语句:
optional<Foo> GetMinElement(vector<Foo> foos) {
vector<Foo>::iterator min_foo = std::min_element(foos.begin(), foos.end());
bool found_min_element = (min_foo != foos.end());
if (found_min_element) {
return *min_foo;
} else {
return nullopt;
}
}
使用三元运算符:
optional<Foo> GetMinElement(vector<Foo> foos) {
vector<Foo>::iterator min_foo = std::min_element(foos.begin(), foos.end());
bool found_min_element = (min_foo != foos.end());
return found_min_element ? optional<Foo>(*min_foo) : optional<Foo>(nullopt);
}
天真地,我只是希望能够将stl
算法的输出传递给optional<T>
构造函数,并让它处理检查空指针的逻辑。这有什么成语吗?
您必须记住,结束迭代器不是空指针。 如果范围是子范围,它甚至可以是有效的迭代器。
我编写自己的范围算法。 它们遵循与您的模式不同的模式。
范围算法采用class Range
,执行启用 adl 的 begin
/end
并运行迭代器算法。 然后它返回一个可选的迭代器(如果end
为空)。
这与您的略有不同,因为我不会返回元素的副本。
它们可以在原件所在的任何地方使用(添加make_range(start,finish)
)。
如果您不喜欢 if 和 ?
的语法,这些可能会有所帮助:
template<class T>
std::optional<std::decay_t<T>> maybe(bool engage, T&&t){
if (!engage) return {};
return std::forward<T>(t);
}
甚至:
templace<class F>
std::optional<std::decay_t<std::result_of_t<F()>>>
perhaps(bool do_it, F&&f){
if (!engage) return {};
return std::forward<F>(f)();
}
像?
一样短路。
namespace adl_helper{
using std::begin; using std::end;
template<class R> auto adl_begin(R&&)->decltype(begin(std::declval<R>())){
return begin(std::forward<R>(r));
}
template<class R> auto adl_end(R&&)->decltype(end(std::declval<R>())){
return end(std::forward<R>(r));
}
}
using adl_helper::adl_begin;
using adl_helper::adl_end;
template<class R>using iterator_t=decltype(adl_begin(std::declval<R>()));
template<class R>
optional<iterator_t<R>> min_element(R&& r) {
auto ret = std::min_element(adl_begin(r), adl_end(r));
return maybe(ret!=adl_end(r), ret);
}
我发现它比你的版本更有用。
您有时确实需要做额外的*
,或使用助手。
optional 似乎没有一个构造函数,该构造函数有时会产生一个空的可选函数,而sumetimes会产生一个完整的可选函数。
也许你可以做一个帮手:
template<typename Iter>
optional<typename Iter::value_type> try_deref(Iter pos, Iter singular)
{
if ( pos != singular )
return *pos;
return {};
}
示例用法:
optional<Foo> GetMinElement(std::vector<Foo> const &foos)
{
auto min_foo = std::min_element(foos.begin(), foos.end());
return try_deref(min_foo, foos.end());
}
相关文章:
- 如何在不销毁对象的情况下返回对象列表
- 如何在不使用临时变量的情况下取消引用返回指针的函数的返回值?
- G++ 编译器是否在未使用返回值的情况下将 constexpr 函数视为常规函数?
- 如何在没有返回值的情况下使用(特征)unaryExpr 和 lambda 函数?
- C++箭头运算符 (->) 是否在所有情况下都返回左值?
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- UDP 套接字 select() 在某些情况下无延迟(超时)返回 1
- 串行读取()不会在没有数据接收的情况下返回值
- 如何在没有运算符>>的情况下从字符串流返回下一个令牌?
- 为什么在某些情况下从函数返回类型中删除 cv 限定符?
- 如何在不使用 STL 的情况下从函数反转字符串后返回字符串C++?
- 如何在不返回 C++ 值的情况下退出 int 函数?
- 如果在开关情况下不匹配,为什么此函数返回 ASCII 值?
- 在这种情况下,如何返回对数组中元素的引用?
- 在开关情况下返回布尔值
- 谷歌嘲笑!我的测试出错.默认情况下,呼叫将返回调用
- 如何在不使用返回的情况下从函数获取变量的地址(指针)
- 范围分辨率运算符在类型:: var的情况下返回什么
- -std=c++0x 导致在 boost 1.64 的情况下返回对临时的引用
- 如何在不转换回基类类型的情况下返回派生类型的对象?