#include #include struct base { virtual ~base() {}; }; struct derived : base { }; struct otherderived : base { }; template< class T> struct wrapper { explicit wrapper( T* ptr0) : ptr( ptr0) {} T* ptr; }; template< class derived, class base> bool cmm_dynamic_test( wrapper< base> x) { base* y = x.ptr; if ( dynamic_cast< derived*>( y)) { return true; } return false; } template< class derived, class base> wrapper< derived> cmm_static_cast( wrapper< base>& b) { return wrapper< derived>( static_cast< derived*>( b.ptr)); } template< class base> const std::type_info& cmm_typeid( const wrapper< base>& x) { return typeid( *x.ptr); } void bar( wrapper< virtual base>); void bar_( wrapper< static derived> b) { std::cout << "bar_( wrapper< static derived> b) called\n"; (void) b; } void bar_( wrapper< static otherderived> b) { std::cout << "bar_( wrapper< static otherderived> b) called\n"; (void) b; } int main() { try { wrapper< base> x( new derived); wrapper< base> y( new otherderived); wrapper< base> z( new base); bar( x); bar( y); //bar( z); // causes deliberate dispatch error. return 0; } catch( std::exception& e) { std::cerr << e.what() << "\n"; } return 1; }