#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;
}