CRTPを使用してポリシーを実装しました。ポリシーでは、Base
クラスにfooという関数が必要です。
template<typename Base>
struct Policy<Base> {
// ...
Base* b(){ return static_cast<Base*>(this); }
void do(){ b()->foo(); }
};
Widget
ポリシーを使用するというクラスが1つあります。Widget
実装foo
し、すべてが正常です:
struct Widget : Policy<Widget> {
// ...
void foo();
};
問題::という名前OldWidget
の関数での機能を実装するというタイプもあります。foo
oldFoo
struct OldWidget : Policy<OldWidget> {
// ...
void oldFoo();
};
OldWidgetを変更したくありません(ポリシーで拡張する以外に)。使用したくないAdaptedOldWidget
:
struct AdaptedOldWidget : OldWidget, Policy<AdaptedOldWidget> {
void foo(){ oldFoo(); }
};
policy_traits
最善の方法は、既存のクラスを次のようなものに拡張することです。
template<typename T>
struct policy_traits {};
template<>
struct policy_traits<Widget> {
// typedefs...
member_function_name = foo;
};
template<>
struct policy_traits<OldWidget> {
// typedefs
member_function_name = oldFoo;
};
このようなポリシーを実装できるように:
template<typename Base>
struct Policy<Base> {
// ...
Base* b() { return static_cast<Base*>(this); }
void do(){ b()->policy_traits<Base>::member_function_name(); }
};
C ++でこのようなことを達成する方法はありますか?
提案された解決策:私は次のことを行うことができます:
template<typename Base>
struct Policy<Base> : Policy_Member_Traits<Base> {
// ...
Base* b(){ return static_cast<Base*>(this); }
void do(){ foo_wrapper(); }
};
template<typename T> struct Policy_Member_Traits { };
template<> struct Policy_Member_Traits<Widget> {
void foo_wrapper(){ static_cast<T*>(this)->foo(); }
};
template<> struct Policy_Member_Traits<OldWidget> {
void foo_wrapper(){ static_cast<T*>(this)->oldFoo(); }
};
うまくいけば、これを達成するためのより簡単な方法があるはずです。