仕事では NO_RTTI ばっかりだったし必要な書き方をしてなかったので dynamic_cast 自体の必要性も謎なのだけど頭の体操のつもりで代替処理を書いてみた。 20年不要だったので今後も身の回りでは不要だろうとは思う。
#include <type_traits>
class DynamicCastable {
protected:
/// 型式別に使う関数
template<typename T> static void Type() {};
/// 型式別に使う関数の型
typedef void (*TypeFunc)();
/// 型判別仮想関数
inline virtual auto Is(TypeFunc fn) const -> bool {
return &Type<DynamicCastable> == fn;
}
public:
/// 型判別
template<typename T>
inline auto Is() const -> bool { return Is(&Type<T>); }
};
/// 動的型変換
template<typename T, typename E>
inline auto DynamicCast(E* e) -> T {
typedef typename std::remove_pointer<T>::type type;
return e->template Is<type>() ? static_cast<T>(e) : nullptr;
}
class One : public DynamicCastable {
protected:
inline auto Is(TypeFunc fn) const -> bool override {
// 失敗したら基底へ
return &Type<One> == fn || DynamicCastable::Is(fn);
}
};
class Two : public One {
protected:
inline auto Is(TypeFunc fn) const -> bool override {
// 失敗したら基底へ
return &Type<Two> == fn || One::Is(fn);
}
};