Alternative für "virtual template"
-
Ich habe eine Klasse:
class A { template <class Iterator> unsigned hashFunction(Iterator begin, Iterator end) { // ... } template <class Iterator> void doSomething(Iterator begin, Iterator end) { // viel Code, in dem u.a. hashFunction aufgerufen wird } };Ich möchte jetzt eine zweite Klasse B schreiben, die quasi von A erbt, bei der aber eine andere "hashFunction"-Implementierung verwendet wird. Die doSomething-Implementierung soll so bleiben wie bei A. Beim Aufruf von doSomething auf einem B-Objekt soll dann natürlich die hashFunction-Implementierung von B verwendet werden.
Wären die beiden Methoden keine Templates, würde ich hashFunction als virtual deklarieren und alles wäre gut.
Was gibt es in meinem Fall für Alternativen?
Das einzige was mir gerade einfällt, ist die doSomething-Implementierung von A nach B zu kopieren. Das ist ziemlich unschön, vor allem, wenn man doSomething mal ändern möchte...
-
template<class Iterator> class A { virtual unsigned hashFunction(Iterator begin, Iterator end) { // ... } void doSomething(Iterator begin, Iterator end) { // viel Code, in dem u.a. hashFunction aufgerufen wird } };und jetzt ableiten
-
Oder type erasure auf den Iterator machen.
-
Meep Meep schrieb:
template<class Iterator> class A { virtual unsigned hashFunction(Iterator begin, Iterator end) { // ... } void doSomething(Iterator begin, Iterator end) { // viel Code, in dem u.a. hashFunction aufgerufen wird } };und jetzt ableiten
Und was ist, wenn ich doSomething mit verschiedenen Iterator-Instanzen auf demselben A-Objekt verwenden will? -> geht so nicht.
Type Erasure guck ich mir mal an.
Edit:
Ich glaube, ich habe eine Lösung gefunden, die meinen Bedürfnissen entspricht:
Ich lager die hashFunction aus und übergebe sie als Template-Parameter:#include <iostream> #include <vector> template <template <class> class hashFunction> struct A { template <class Iterator> unsigned doSomething(Iterator begin, Iterator end) { hashFunction<Iterator> h; return h(begin, end); } }; template <class X> struct hash { unsigned operator()(X a, X b) { return b - a; } }; template <class X> struct hash2 { unsigned operator()(X a, X b) { return 2*(b - a); } }; int main() { A<hash> a; A<hash2> b; std::vector<int> v(10); std::cout << a.doSomething(v.begin(), v.end()) << std::endl; std::cout << b.doSomething(v.begin(), v.end()) << std::endl; }