#include <iostream>
#include <string>
#include <exception>
using namespace std;
////////////////////////////////////////////////////////////////////////////////
template <class T>
bool inspect(exception_ptr p, void (&fun)(T))
{
try
{
if (p != exception_ptr())
rethrow_exception(p);
}
catch (T t)
{
fun(t);
return true;
}
catch (...)
{
return false;
}
}
////////////////////////////////////////////////////////////////////////////////
class printable
{
public:
virtual void print() const = 0;
};
////////////////////////////////////////////////////////////////////////////////
class foo : public printable
{
public:
foo(string const& s) : m_s(s) {}
virtual void print() const
{
cout << "foo: " << m_s << "\n";
}
private:
string m_s;
};
class bar : public printable
{
public:
bar(int i) : m_i(i) {}
virtual void print() const
{
cout << "bar: " << m_i << "\n";
}
private:
int m_i;
};
////////////////////////////////////////////////////////////////////////////////
void print_printable(printable& p)
{
p.print();
}
////////////////////////////////////////////////////////////////////////////////
int main()
{
auto f = make_exception_ptr(foo("foo"));
auto b = make_exception_ptr(bar(42));
inspect(f, print_printable);
inspect(b, print_printable);
return 0;
}