How does std :: current_exception work?

Viewed 1979

Consider the following example:

class myclass
{
public:

    void f() const
    {
        std :: cout << "Hello from myclass!" << std :: endl;
    }
};

int main()
{
    std :: exception_ptr x;

    try
    {
        throw myclass();
    }
    catch(...)
    {
        x = std :: current_exception();
    }

    try
    {
        std :: rethrow_exception(x);
    }
    catch(const myclass & n)
    {
        n.f();
    }
}

Here I throw an object of class myclass and use std :: current_exception() in the catch(...) block to get a std :: exception_ptr. Later I use std :: rethrow_exception to get the exception thrown again and I catch it, this time with catch(const myclass &), that allows me to, e.g., call f() and get Hello from myclass! printed out.

Now. I kind of imagine how I could implement something similar to std :: exception_ptr: a pointer to a base class, from which a template wrapper for each possible type inherits, and some rethrow virtual method that allows to throw again the exception. So far so good.

Now, how does std :: current_exception() work? How is it implemented? I tried to inspect it using my Xcode but I got a nice flashing question mark: ?. Is this some kind of primitive in C++11? Like, e.g., decltype or sizeof? Or is there another way to access the exception hidden in that catch(...)?

For example, is there a way to just print out an exception, whatever it is? Something like:

template <typename type> void printme(const type & exception)
{
    try
    {
        throw exception;
    }
    catch(...)
    {
        std :: cout << /* SOME MAGIC HERE */ << std :: endl;
    }
}

I guess that std :: current_exception() would be using some similar way to access the exception, make a copy of it, and instantiate an appropriate std :: exception_ptr that can be later rethrown.

So am I missing something? I tried something trivial like catch(auto x) but it doesn't seem to do the job.

1 Answers
Related