std::packaged_task is a facility of c++ asynchronous programming std::future.
std::packaged_task can make exception across threading work.
#include <future>
#include <iostream>
#include <thread>
#include <chrono>
#include <functional>
#include <complex> // std::sqrt
#include <memory>
#include <mutex>
namespace across
{
std::mutex print_mutex;
class my_task_class
{
private:
std::shared_ptr<std::packaged_task<double(int)>> __task;
std::jthread __thrd;
std::future<double> __future;
public:
my_task_class()
{
}
public:
virtual ~my_task_class()
{
__task = {};
}
public:
void run(int value)
{
__task = std::make_shared<std::packaged_task<double(int)>>(
std::bind(
&across::my_task_class::my_task,
this,
std::placeholders::_1
)
);
__future = __task->get_future();
__thrd = std::jthread{
std::move(* std::move(__task)),
value
};
__task = {};
}
public:
double get()
{
return __future.get();
}
protected:
double my_task(int x)
{
if (x < 0)
throw std::runtime_error{"Error: Negative Value!"};
return std::sqrt(x);
}
};
}
int main()
{
for (int i=-3; i<=3; ++i)
{
across::my_task_class task;
try
{
task.run(i);
double result = task.get();
std::unique_lock<std::mutex> lock{across::print_mutex};
std::cout << "Result: " << result << std::endl;
}
catch (const std::exception & e)
{
std::unique_lock<std::mutex> lock{across::print_mutex};
std::cout << "c++ std::exception: " << e.what() << std::endl;
}
}
}
Mon Aug 11 11:21:51 PM UTC 2025