Another default action exists for result<T, EC> where trait::has_exception_ptr<EC> is true, and for outcome<T, EC, EP> where either or both trait::has_exception_ptr<EC> and trait::has_exception_ptr<EP> is true.

This default action simply rethrows the exception pointer via std::rethrow_exception(make_exception_ptr(.error())) for result and std::rethrow_exception(make_exception_ptr(.error())) and/or std::rethrow_exception(make_exception_ptr(.exception())) for outcome, if trait::has_exception_ptr<EC> and/or trait::has_exception_ptr<EP> is true.

  struct udt
    int a{0};
    explicit udt(int _a)
        : a(_a)
    udt() = default;
    int operator*() const { return a; }
  result<udt, std::exception_ptr> res(std::make_exception_ptr(std::runtime_error("hello")));

  // What happens here? What exception type is thrown?
    std::cout << *res.value() << std::endl;
  catch(const std::exception &e)
    std::cerr << "Exception thrown was " << e.what() << std::endl;
View this code on Github

Running this yields:

ned@lyta:~/outcome/build_posix$ bin/outcome-snippets_exception_ptr
Exception thrown was hello