Ich versuche, die folgende Strömung zu erzeugen:Aufruf abgeleitete Template-Klasse-Methode von der Basis nicht-Template-Klasse
eine ‚Base‘ Klasse, ohne params oder Funktionalität nur so kann ich Basis Zeiger, halte in eine Methode.
Die abgeleitete Klasse ist eine Vorlage, die operator() für einen gegebenen Template-Argument-Objekttyp implementiert.
Ich versuche, indem Sie einen Zeiger auf die Basisklasse verwenden, den abgeleiteten Klassenoperator() in der Laufzeit aufrufen.
Ich habe versucht, es mit der Umsetzung CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) Aber das scheint nicht die-andere-Wege-um zu arbeiten - wenn die abgeleitete Klasse eine Klassenvorlage ist.
Hier ist mein Code:
class Base {};
template<typename Ref_Obj, typename Obj_Type>
class Derived : public Base {
private:
typedef bool (Ref_Obj::*Func_p)(Obj_Type) const;
Func_p m_func;
const Ref_Obj& m_db;
public:
Derived<Ref_Obj, Obj_Type>(const Ref_Obj& db, Func_p func): m_db(base), m_func(filter) {}
inline bool operator()(const Obj_Type& obj) const {
return (m_db.*m_func)(obj);
}
}
Nun ist die Nutzung in einem anderen Klassenvorlage, die Vektor der Basisklasse Zeiger enthält, wie folgt, und haben einen eigenen Operator():
template<typename Obj_Type2> /* Upon usage, Obj_Type2 is the same as Obj_Type, this is just to differ the two in the code here */
class BlaBla {
private:
std::vector<const Base *> m_vec;
public:
/* relevant constructors ... */
inline bool operator()(const Obj_Type2 &obj) const {
for(std::vector<const Base *>::const_iterator it = m_vec.begin(); it != m_vec.end(); ++it) {
/*** This is the problematic line V ***/
if((*it).operator()(obj)) { /* DO SOMETHING */ }
}
}
Natürlich beschwert sich der Compiler, dass es in der problematischen Zeile, die in dem Code unten markiert ist, keine übereinstimmende Funktion gibt, aber die Art, den entsprechenden Aufruf auszuführen, kann ich nicht herausfinden.
erste Lösung in den Sinn kam, einen virtuellen Betreiber zu erstellen ist() (...) mit einem bestimmten Objekttyp z.B. virtueller Operator() (const uint32_t & Obj) in der Basisklasse, die funktioniert, aber meine Absicht ist, dass operator() (...) eine Vielzahl von Objekttypen erhalten wird, und eine virtuelle Methode für jede von ihnen nicht angibt elegant und scheint zu brechen alle Template-Konzept, das ich hier implementieren möchte.
zweite Lösung in dem Sinne kam, irgendwie Ref_Obj und obj_type typenames zu Basisklasse ist vorbei, in einer Art Interface-Methode verwendet werden, das static_cast verwendet den entsprechenden Abgeleitet Operator anrufen (wie in CRTP) - Aber das scheint nicht zu funktionieren, da die abgeleitete Klasse eine Klassenvorlage ist und auch die Klasse BlaBla nicht direkt weiß Ref_Obj typename.
Gibt es eine andere Möglichkeit, den entsprechenden Aufruf an Deriver operator()
Was ist das Spektrum von Typen, die Sie zu abgeleitet 'Operator()' übergeben möchten? Wenn sie alle einen gemeinsamen Vorfahren 'TypeBase' teilen, können Sie das geschützte' virtuelle bool Base :: operator() (TypeBase &) 'und das öffentliche' template bool Base :: operator() (T &) 'als virtuell implementiert erklären , in abgeleiteten Klassen überschrieben. –
Mikhail
Sie haben keinen gemeinsamen Vorfahren, da sie Klassenzeiger, primitive Typen usw. sein können. – Adiel