c++ - 一般返回一个可选的<T>/nullopt

标签 c++ templates c++17 std

我正在尝试实现一个通用的 find_if_opt 方法,该方法实际上与 std::ranges::find_if 相同(但它返回一个可选)

到目前为止,这是我的实现。

    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:如果您对我的 range::包装器有任何建议,而我仍然停留在 c++17 上,请随时提出。

最佳答案

您可以使用ranges::range_value_t获取 X

value_type
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)>>{};
}

关于c++ - 一般返回一个可选的<T>/nullopt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70367406/

相关文章:

c++ - 安卓 native NDK OpenGL ES : unimplemented API

从 Boost object_pool 构造的指针的 C++ Boost 二进制序列化

c++ - std::array 类成员在编译时设置?

c++ - 使用多个参数值调用模板函数

c++ - istrstream 的更好替代品?

c++ - 将 xml 字符串嵌套到 xml 元素中的语法

c++ - 如何修复通过重载和模板化的插入运算符尝试显示字符串对象数组而产生的空白输出?

C++17模板参数推导之谜

c++ - 在 SFML 中不使用 Sprite 显示图像

c++ - 删除 C 风格的 int vector 数组