Temporary optional expression for loop expression

Suppose we have a function that returns std::optional<A>. Then what is the correct way to use the result in a range-based loop? The easiest way does not work:

for (auto&& e : a().value()) {
                   // ^--- A&& is returned, so A is destructed
                   // before loop starts

This problem would not exist if we used T optional::value() &&instead T&& optional::value() &&, but both STL and Boost define it in a second way.

What is the right way to deal with this situation? I don't like both solutions I could think of ( sandbox ):

std::experimental::optional<A> a() {
  // ...
}

void ok1() {
  // ugly if type of A is huge
  for (auto&& e : A(a().value())) {
     // ...
  }
}

void ok2() {
  // extra variable is not used
  // if for some reason we are sure that we have a value
  // and we skip checks
  auto&& b = a();
  for (auto&& e : b.value()) {
    // ...
  }
}

// it may be that the best choice is to define
A aForced() {
    return A(a().value());
}
+4
source share
1 answer

This solves your problem:

template<class T>
std::decay_t<T> copy_of(T&& t){
  return std::forward<T>(t);
}

template<class T, std::size_t N>
void copy_of(T(&)[N])=delete;

Then:

for(auto&& x:copy_of(a().value()))

copy_of , rvalue, for(:).


value_or_run(T&&, F&&f), , . F , , throw, T a T&&.

, value_or.

optional emplace value_or - , , , .value_or( throw_if_empty{} ), throw_if_empty throw_if_empty, .

+2

All Articles