Checked static cast by reference

Once upon a time, I created the following template to get a statement when I execute static_cast, but the type is not what I assume:

/// perform a static_cast asserted by a dynamic_cast
template <class Type, class SourceType>
Type static_cast_checked(SourceType item)
{
  Assert(!item || dynamic_cast<Type>(item));
  return static_cast<Type>(item);
}

Today I wanted to create an option that will work not only with pointers, but also with links:

/// overload for reference
template <class Type, class SourceType>
Type &static_cast_checked(SourceType &item)
{
  Assert(dynamic_cast<Type *>(&item));
  return static_cast<Type>(item);
}

However, the compiler does not seem to use this overload when I use a link to another link. I am afraid that I do not understand the rules for resolving patterns in order to understand why, or to be able to create an option that works.

Note. I cannot catch bad_cast exceptioninstead of checking dynamic_cast<Type *>for NULL, because exceptions for this project are disabled.

+5
source share
4 answers

* & :

/// perform a static_cast asserted by a dynamic_cast 
template <class Type, class SourceType> 
Type static_cast_checked(SourceType *item) 
{ 
  Assert(!item || dynamic_cast<Type>(item)); 
  return static_cast<Type>(item); 
} 

template <class Type> struct make_pointer
{
    typedef Type *PointerType;
};

template <class Type> struct make_pointer<Type &>
{
    typedef Type *PointerType;
};

/// overload for reference 
template <class Type, class SourceType> 
Type static_cast_checked(SourceType &item) 
{ 
  Assert(dynamic_cast<typename make_pointer<Type>::PointerType>(&item)); 
  return static_cast<Type>(item); 
} 

:

Derived *d= static_cast_checked<Derived *>(b);
Derived &d= static_cast_checked<Derived &>(b);

EDIT: .

+5

:

/// perform a static_cast asserted by a dynamic_cast
template <class Type, class SourceType>
Type* static_cast_checked(SourceType *item)
{
  Assert(!item || dynamic_cast<Type*>(item));
  return static_cast<Type*>(item);
}

/// overload for reference
template <class Type, class SourceType>
Type &static_cast_checked(SourceType &item)
{
  Assert(dynamic_cast<Type *>(&item));
  return static_cast<Type&>(item);
}

:

Dervied d;
Base* pbase = static_cast_checked<Base>(&d);
Base& rbase = static_cast_checked<Base>(d);

. , , . , ! .

+2
#include <boost/type_traits/add_pointer.hpp>

template <class Type, class SourceType>
Type static_cast_checked(SourceType *item)
{
  assert(!item || dynamic_cast<Type>(item));
  return static_cast<Type>(item);
}

template <typename Type,  class SourceType>
Type static_cast_checked(SourceType &item)
{
   typedef typename boost::add_pointer<Type>::type TypePtr;
   assert(dynamic_cast< TypePtr >(&item));
   return static_cast<Type>(item);
}

static_cast dynamic_cast std-lib: ``

    Base &b    = static_cast_checked<Base&>( a);
    Base* bPtr = static_cast_checked<Base*>(&a);
+1

:

template<class Type, class SourceType>
Type* static_cast_checked(SourceType* item)
{
    // ... 
}

template<class Type, class SourceType>
Type& static_cast_checked(SourceType& item)
{
    // ... 
}

, (IIRC).

0

All Articles