一般 return 可选 <T> / nullopt
Generically return a optional<T> / nullopt
我正在尝试实现一个通用的 find_if_opt
方法,它实际上与 std::ranges::find_if
相同(但是它 return 是可选的)
到目前为止这是我的实现。
template <typename X, typename Z>
inline auto find_if_opt(const X& ds, const Z& fn) {
const auto it = ranges::find_if(ds, fn);
if (it != end(ds)) {
return std::make_optional(*it);
}
return {};
}
auto test() {
std::vector v{1,2,3,4,5};
return ranges::find_if_opt(v, [](auto i){
return i == 2;
});
}
这是一个更大的 std::ranges 的一部分,类似于 c++17 算法的包装器。请参阅 https://godbolt.org/z/3fEe8bbh9(完整相关 header)
当使用 {}
时,编译器错误是:
<source>:29:16: error: cannot deduce return type from initializer list
return {};
^~
我也尝试过使用 std::nullopt,这会导致:
<source>:41:6: required from here
<source>:30:21: error: inconsistent deduction for auto return type: 'std::optional<int>' and then 'std::nullopt_t'
return std::nullopt;
^~~~~~~
PS:如果您对我的 ranges::wrapper 有任何建议,而我仍然停留在 c++17 上,请随时提出。
您可以使用 ranges::range_value_t
获得 value_type
个 X
template <typename X, typename Z>
inline std::optional<std::ranges::range_value_t<X>>
find_if_opt(const X& ds, const Z& fn) {
const auto it = std::ranges::find_if(ds, fn);
if (it != end(ds)) {
return *it;
}
return {};
}
或使用std::iter_value_t
得到迭代器value_type
template <typename X, typename Z>
inline auto
find_if_opt(const X& ds, const Z& fn) {
const auto it = std::ranges::find_if(ds, fn);
if (it != end(ds)) {
return std::make_optional(*it);
}
return std::optional<std::iter_value_t<decltype(it)>>{};
}
或 C++20 之前的版本
template <typename X, typename Z>
inline auto find_if_opt(const X& ds, const Z& fn) {
const auto it = ranges::find_if(ds, fn);
if (it != end(ds)) {
return std::make_optional(*it);
}
return std::optional<std::decay_t<decltype(*it)>>{};
}
我正在尝试实现一个通用的 find_if_opt
方法,它实际上与 std::ranges::find_if
相同(但是它 return 是可选的)
到目前为止这是我的实现。
template <typename X, typename Z>
inline auto find_if_opt(const X& ds, const Z& fn) {
const auto it = ranges::find_if(ds, fn);
if (it != end(ds)) {
return std::make_optional(*it);
}
return {};
}
auto test() {
std::vector v{1,2,3,4,5};
return ranges::find_if_opt(v, [](auto i){
return i == 2;
});
}
这是一个更大的 std::ranges 的一部分,类似于 c++17 算法的包装器。请参阅 https://godbolt.org/z/3fEe8bbh9(完整相关 header)
当使用 {}
时,编译器错误是:
<source>:29:16: error: cannot deduce return type from initializer list
return {};
^~
我也尝试过使用 std::nullopt,这会导致:
<source>:41:6: required from here
<source>:30:21: error: inconsistent deduction for auto return type: 'std::optional<int>' and then 'std::nullopt_t'
return std::nullopt;
^~~~~~~
PS:如果您对我的 ranges::wrapper 有任何建议,而我仍然停留在 c++17 上,请随时提出。
您可以使用 ranges::range_value_t
获得 value_type
个 X
template <typename X, typename Z>
inline std::optional<std::ranges::range_value_t<X>>
find_if_opt(const X& ds, const Z& fn) {
const auto it = std::ranges::find_if(ds, fn);
if (it != end(ds)) {
return *it;
}
return {};
}
或使用std::iter_value_t
得到迭代器value_type
template <typename X, typename Z>
inline auto
find_if_opt(const X& ds, const Z& fn) {
const auto it = std::ranges::find_if(ds, fn);
if (it != end(ds)) {
return std::make_optional(*it);
}
return std::optional<std::iter_value_t<decltype(it)>>{};
}
或 C++20 之前的版本
template <typename X, typename Z>
inline auto find_if_opt(const X& ds, const Z& fn) {
const auto it = ranges::find_if(ds, fn);
if (it != end(ds)) {
return std::make_optional(*it);
}
return std::optional<std::decay_t<decltype(*it)>>{};
}