Brief:Stellen Sie sicher, dass die Klasse von übergeordneten CRTP Klasse abgeleitet implementiert Funktion
ich eine abgeleitete Klasse sicherstellen möchten, dass durch eine Funktion innerhalb des übergeordneten CRTP Klasse erforderlich, um eine Member-Funktion implementiert.
Detail:
Ich habe einige Code wie dieses
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);
};
Die Absicht ist, dass ich mehrere Imp
Kind Klassen alle verschiedene Dinge tun in myFunc
und akzeptieren ihre eigenen erforderlichen Parameter haben kann. Die von Base
bereitgestellte Schnittstelle wird dann von Funktionen auf höherer Ebene verwendet, die nur einen Zeiger/eine Referenz des Typs Base::Params
und Base
benötigen. Mein Problem ist sicherzustellen, dass alle Imp
bietet eine spezialisierte myFunc
. Um eine unendliche Rekursion zu vermeiden, muss Imp
myFunc
implementiert werden.
Mein erster Versuch wurde das Hinzufügen einer rein virtuelle Funktion CRTP
virtual void myFunc(typename T::Params& p) = 0;
aber das funktioniert nicht wie Imp
nicht vollständig definiert, wenn CRTP
definiert wird. This question verwendet eine static_assert
, die mich dazu gebracht hat, das gleiche mit der static_assert
innerhalb CRTP::myFunc
zu tun. Nur bin ich nicht sicher, was der Ausdruck in der statischen Behauptung für eine nicht statische Funktion sein soll.
- Kann ich ein
static_assert
für das verwenden, was ich brauche? - Ist das der beste/sauberste Weg, um sicherzustellen, dass die abgeleitete Klasse die benötigte Funktion hat?
- Habe ich mich von meinem Klassenentwurf mitreißen lassen und es gibt einen besseren Weg, Dinge zu tun?
Danke.
können Sie nicht SFINAE Magie verwenden, um festzustellen, ob 'Imp :: Param' sich von' Base :: Param' unterscheidet und dass 'Imp :: myFunc()' 'Imp :: Param' als Argument verwendet? – Walter
@Walter für die zweite, wenn es Vererbung gibt, wird es falsch positive haben. Für den ersten möchten Sie vielleicht nicht verlangen. – Yakk
Neben: Warum sind Sie statische Umwandlung in 'T const *' von einer nicht-'const' Methode? Entweder sollte "myFunc" in "Base" und "CRTP" "const" sein, oder Sie sollten 'static_cast' in der 'CRTP'-Implementierung aufrufen. –
Yakk