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.
This works:

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

```

Use it like this:

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

```

This solution relies on overloading function templates. Your solution didn't work because your first template is too general, it already includes your second function. Note that there is no specialization for function templates! You can only specialize class templates.