Question: Long ago I have created a following template so that I get an assert whenever I perform a static\_cast but the type is not what I assume it to be:

```
/// 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 a variant which would work not only with pointers, but with references as well:

```
/// 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 am casting a reference to another reference. I am afraid I do not understand template resolution rules enough to understand why, or to be able to create a variant which works.

*Note: I cannot catch the `bad_cast exception` instead of checking `dynamic_cast<Type *>` for NULL, as exceptions are disabled for this project.*

Answer: 
Remove `*` and `&` from the return types:

```
/// 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); 
} 

```

Then you can use your desired syntax: 

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

```

EDIT: added a pointer type conversion.
Try the following:

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

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

```

Then every pointer would use the first variant and every reference will use the second at the rules of partial specialization (IIRC).