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,因为此项目禁用了异常.
从返回类型中删除*和&:
/// 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)
编辑:添加了指针类型转换.