URL: https://www.overclockers.at/coding-stuff/c-virtual-template-workaround_248373/page_1 - zur Vollversion wechseln!
mein arduino kann kommandos über verschiedene schnittstellen empfangen (serial, ethernet, wlan, ...), die (bisher voneinander getrennten) klassen dafür würde ich gerne unter einer base class versammeln.
in den derived classes wird es function templates geben, die in allen gleich heißen und existieren müssen und die ich deshalb gerne in der base class repräsentiert hätte (z.b. als pure virtual functions). leider erlaubt c++ keine virtual templates. hat jemand eine idee wie ich das (oder etwas vergleichbares) machen könnte?
Code: CPPclass CommandInterface { public: CommandInterface(); virtual ~CommandInterface(); virtual template <class T> size_t print(T& message) = 0; //geht leider nicht :( virtual template <class T> size_t println(T& message) = 0; }; class CommandInterfaceSerial : public CommandInterface { public: CommandInterfaceSerial(); ~CommandInterfaceSerial(); template <class T> size_t print(T& message) { return Serial.print(message); } template <class T> size_t println(T& message) { return Serial.println(message); } };
Kannst du ein paar Beispiele für die Template Parameter nennen, die man in print und println reinschmeißen würde? Grad in einem vorab definierten Protokoll würde ich eigentlich davon ausgehn, dass diese von gleichem oder ähnlichen Typ sein müssen?
Eine Möglichkeit wäre wohl, dem CommandInterface einen Template Parameter für die tatsächliche Implementierung aufzudrücken. Sowas wie
Code: CPPtemplate<typename Implementation> class CommandInterface { template<typename T> size_t print(T& msg) { impl.print(T); } // ev. std::forward... private: Implementation impl; }
Ja, das geht leider nicht. Der Grund dafür ist:
ZitatMember function templates cannot be declared virtual. This constraint is imposed because the usual implementation of the virtual function call mechanism uses a fixed-size table with one entry per virtual function. However, the number of instantiations of a member function template is not fixed until the entire program has been translated. Hence, supporting virtual member function templates would require support for a whole new kind of mechanism in C++ compilers and linkers. In contrast, the ordinary members of class templates can be virtual because their number is fixed when a class is instantiated.
byte, char, int (8,16,32 bit, signed & unsigned), float, String.Zitat von VinciKannst du ein paar Beispiele für die Template Parameter nennen, die man in print und println reinschmeißen würde? Grad in einem vorab definierten Protokoll würde ich eigentlich davon ausgehn, dass diese von gleichem oder ähnlichen Typ sein müssen?
damit habe ich noch nie gearbeitet, ich schaue mir das noch an.Zitat von VinciEine Möglichkeit wäre wohl, dem CommandInterface einen Template Parameter für die tatsächliche Implementierung aufzudrücken. Sowas wieCode: CPPtemplate<typename Implementation> class CommandInterface { template<typename T> size_t print(T& msg) { impl.print(T); } // ev. std::forward... private: Implementation impl; }
Schön is das imho nicht.
moment, nochmal für freizeit- c++ler bitte. die von CommandInterface abgeleiteten klassen sind wrapper für die verschiedenen schnittschnellen, die über ein gemeinsames interface genutzt werden können sollen... ich stehe gerade auf der leitungZitat von VinciIch persönlich würde übrigens das CommandInterface nicht mit der Schnittstelle in Verbindung bringen, schon gar nicht via Vererbung.
auf bost würde ich gerne verzichten, wäre imho overkill. müsste ich für type erasure nicht alle datentypen wrappen? ( https://en.wikibooks.org/wiki/More_...ms/Type_Erasure )Zitat von matEine akzeptable Alternative, um dieses Problem zu umgehen, ist Type Erasure. Die bekannteste Implementierung davon ist boost::any. Die Template-Funktionen bleiben dann nur in der Basis-Klasse während zusätzliche Funktionen für den Aufruf von außen zur Verfügung stehen und den Typ boost::any entgegen nehmen.
overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2025