Есть ли способ узнать, бросит ли будущее get ()? - PullRequest
2 голосов
/ 06 ноября 2019

Есть ли способ узнать, будет ли будущее выбрасывать get()?

Скажем, у меня есть что-то вроде этого:

#include <cstdlib>
#include <future>
#include <stdexcept>
#include <iostream>

int main() {
  srand(time(0));
  auto randomSuccess = [] {
             if (rand() >= rand())
                  throw std::runtime_error("Random exception");
             };
  auto f = std::async(std::launch::deferred, randomSuccess);

  f.wait();
  // from here, the future is valid
  std::cout << "Now future is " << (f.valid() ? "valid" : "not valid yet") << std::endl;

  f.get(); // how to know if this will throw?
}

Я бы просто хотел "шпионить"внутреннее состояние будущего, точно так же, как bool valid() const noexcept; делает, оставляя будущее нетронутым (функция будет const), поэтому помещать блок try/catch не то, что я хочу делать.

Ответы [ 2 ]

1 голос
/ 06 ноября 2019

Вы можете сделать гимнастику, чтобы получить результат:

template <typename T>
bool will_throw(std::future<T>& fut)
{
    std::promise<T> promise;
    try {
        if constexpr (std::is_void<T>::value) {
            fut.get();
            promise.set_value();
        } else {
            promise.set_value(fut.get());
        }
        fut = promise.get_future(); // Restore future value
        return false;
    } catch (...) {
        promise.set_exception(std::current_exception());
        fut = promise.get_future(); // Restore future exception
        return true;
    }
}

Демо

0 голосов
/ 06 ноября 2019

основано на той же идее, что и @ Jarod42, без необходимости поддержки c ++ 17

template <class T>
bool will_throw(std::future<T> &f) {
    bool throws = false;
    auto new_f = std::async(std::launch::deferred, [&throws, &f] () {
       try {
           return f.get();
       } catch (...) {
           throws = true;
           throw;
       }
    });

    new_f.wait();

    f = std::move(new_f);

    return throws;
}
...