c++ 循环遍历std::optional

a8jjtwal  于 2024-01-09  发布在  其他
关注(0)|答案(2)|浏览(161)

我试着在std::optional上写:

  1. for (auto x : optionalValue)
  2. {
  3. ...
  4. }

字符串
如果optionalValue是空的,它什么也不做,但是如果里面有一个值,它会做一次迭代,就像它在Haskell中一样(这可以说使std::optional流行起来):

  1. forM optionalValue
  2. ( \x ->
  3. ...
  4. )


为什么我不能选择可选的?有没有其他更标准的C++方法可以做到这一点?

vx6bjr1n

vx6bjr1n1#

std::optional没有begin()end()对。所以你不能在上面使用基于范围的-for。而只需要使用if条件。

  • 请参阅备选方案2,以获得最接近您想要做的事情。*

编辑:如果你有一个临时的调用结果,你不必显式地检查它:

  1. if (auto const opt = function_call()) {
  2. do_smth(*opt);
  3. }

字符串
static_cast<bool>(opt)的检查由if隐式完成。

备选案文1

另一种选择是不使用std::optional<T>,而是使用std::variant<std::monostate, T>。然后您可以使用overloaded习惯用法或创建自定义类型来处理单态:

  1. template <typename F>
  2. struct MaybeDo {
  3. F f;
  4. void operator()(std::monostate) const {}
  5. template <typename T>
  6. void operator()(T const& t) const { f(t); }
  7. };


这将允许您使用某些函数访问该值:

  1. std::variant<std::monostate, int> const opt = 7;
  2. std::visit(MaybeDo{[](int i) { std::cout << i << "\n"; }}, opt);

  • 备选案文2*

你也可以把optional Package 在一个东西里,这样你就可以把optional覆盖在上面。

  1. template <typename T>
  2. struct IterateOpt {
  3. std::optional<T> const& opt;
  4. struct It {
  5. std::optional<T> const* p;
  6. It& operator++() {
  7. p = nullptr;
  8. return *this;
  9. }
  10. It operator++(int) {
  11. return It{nullptr};
  12. }
  13. auto const& operator*() const { **p; }
  14. };
  15. auto begin() const {
  16. if (opt) return It{&opt};
  17. else end();
  18. }
  19. auto end() const {
  20. return It{nullptr};
  21. }
  22. };


这是如何做到这一点的粗略草图,可能需要一些爱来处理不同的情况(如非常数可选)。
您可以使用此命令“删除”可选的:

  1. for (auto const& v: IterateOpt{function_call()}) {
  2. do_smth(v);
  3. )

展开查看全部
dly7yett

dly7yett2#

你可以使用类似于

  1. for (const auto& x : optionalValue.value()){
  2. //code
  3. }

字符串
这可以抛出std::bad_optional_accesshttps://en.cppreference.com/w/cpp/utility/optional/valuehttps://devblogs.microsoft.com/oldnewthing/20211004-00/?p=105754

相关问题