Brief:確保派生自父類CRTP類的類實現函數
我想確保派生類實現父CRTP類中函數所需的成員函數。
詳細信息:
我有這樣
class Base
{
public:
class Params
{
public:
virtual ~Params() {}
};
virtual void myFunc(Params& p) = 0;
};
template< typename T >
class CRTP : public Base
{
public:
virtual void myFunc(Base::Params& p) override
{
typename T::Params& typedParams = dynamic_cast<typename T::Params&>(p);
static_cast<T*>(this)->myFunc(typeParams);
}
};
class Imp : public CRTP<Imp>
{
public:
class Params : public CRTP<Imp>::Params
{
public:
virtual ~Params() {}
int x, y, z;
};
virtual void myFunc(Imp::Params& p);
};
意圖一些代碼是,我可以在myFunc
多個Imp
子類都在做不同的事情,並接受自己所需的參數。由Base
提供的接口然後被更高級別的功能使用,其僅需要具有類型爲Base::Params
和Base
的指針/參考。我的問題是確保任何Imp
提供專門的myFunc
。爲避免無限遞歸,Imp
必須實現myFunc
。
我的第一次嘗試是將純虛函數CRTP
virtual void myFunc(typename T::Params& p) = 0;
但Imp
尚未完全時,被定義CRTP
定義不起作用。 This question使用static_assert
,這讓我想到CRTP::myFunc
中的static_assert
也是這樣。除非我不確定靜態斷言中對於非靜態函數應該是什麼表達式。
- 我可以使用
static_assert
來滿足需要嗎? - 這是確保派生類具有所需功能的最佳/最乾淨的方法嗎?
- 我有沒有被我的班級設計帶走,還有更好的做事方式?
謝謝。
難道你不能用一些SFINAE魔法來確定'Imp :: Param'是否與'Base :: Param'不同,並且'Imp :: myFunc()'將'Imp :: Param'作爲參數? – Walter
@沃爾特第二,如果有繼承,它會有誤報。首先,你可能不想要這樣做。 – Yakk
另外:爲什麼你從非''constst'方法靜態強制轉換爲'T const *'?在'Base'和'CRTP'中'myFunc'應該是'const',或者你應該在'CRTP'實現中調用'static_cast'。 –
Yakk