If I understand correctly, you can do what you want in C++ without a custom exception handler but not with the syntax you are using. One solution I can see is that you combine virtual functions with the exception mechanism. First you create a base class to make catching easy and give it an interface to allow easy rethrowing of the object itself and its referred to object.
struct shared_exception_base_t {
    virtual void raise_ref() = 0;
    virtual void raise_self() = 0;
};
template <class value_t>
class shared_ptr_t : public shared_exception_base_t {
    value_t* ptr_;
public:
    shared_ptr_t(value_t* const p) : ptr_ (p) { }
    void raise_ref()
    {
        throw *ptr_;
    }
    void raise_self()
    {
        throw *this;
    }
};
template <class value_t>
shared_ptr_t<value_t> mk_with_new()
{
    return shared_ptr_t<value_t>(new value_t());
}
Then you can use the exception mechanism to do the discrimination. Note that the try/catch blocks have to be nested.
#include <iostream>
struct file_exception_t { };
struct network_exception_t { };
struct nfs_exception_t : file_exception_t, network_exception_t { };
struct runtime_exception_t { };
void f()
{
    throw mk_with_new<runtime_exception_t>();
}
int
main()
{
    try {
        try {
            f();
        } catch (shared_exception_base_t& x) {
            try {
                x.raise_ref();
            } catch (network_exception_t& fx) {
                std::cerr << "handling network exception\n"; 
            } catch (file_exception_t& fx) {
                std::cerr << "handling file exception\n"; 
            } catch (...) {
                x.raise_self();
            }
        }
    } catch (...) { 
        std::cerr << "no idea\n";
    }
    return 0;
}