检查参考上的静态强制转换

Sum*_*uma 5 c++ templates casting

很久以前我已经创建了一个以下模板,这样每当我执行static_cast时我都会获得一个断言,但类型不是我认为的类型:

/// 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);
}
Run Code Online (Sandbox Code Playgroud)

今天我想创建一个不仅可以使用指针,还可以使用引用的变体:

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

但是,当我转换对另一个引用的引用时,编译器似乎不使用此重载.我恐怕我不明白模板解析规则足以理解为什么,或者能够创建一个有效的变体.

注意:我无法捕获bad_cast exception而不是检查dynamic_cast<Type *>NULL,因为此项目禁用了异常.

MSN*_*MSN 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); 
} 

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); 
} 
Run Code Online (Sandbox Code Playgroud)

然后你可以使用你想要的语法:

Derived *d= static_cast_checked<Derived *>(b);
Derived &d= static_cast_checked<Derived &>(b);
Run Code Online (Sandbox Code Playgroud)

编辑:添加了指针类型转换.