2017-02-24 4 views
0

Entschuldigung für den uninformativen Titel, ich weiß nicht wirklich, was ich nennen soll, was ich frage.Alternative zum Überladen von Funktionen mit abgeleiteten Typen

Ich möchte Folgendes erreichen: Einen Container eines Basisklassentyps mit Instanzen abgeleiteter Typen haben, auf die Container zugreifen und abhängig vom Typ des abgeleiteten Objekts eine Funktionsüberladung aufrufen. In einer Frage früher habe ich gefragt here Ich habe gelernt, dass das statische Design, das ich bis jetzt im Auge hatte, nicht funktioniert. Die Art und Weise habe ich versucht, ist dies:

struct Int2TypeBase{ 
}; 

template <int v> 
struct Int2Type : public Int2TypeBase 
{ 
    enum 
    { 
     value = v 
    }; 
}; 


void f(const Int2Type<0>&){ 
    std::cout << "f(const Int2Type<0>&)" << "\n"; 
} 

void f(const Int2Type<1>&){ 
    std::cout << "f(const Int2Type<1>&)" << "\n"; 
} 


int main(){ 
    using namespace std; 

    std::vector<std::reference_wrapper<Int2TypeBase>> v; 

    Int2Type<0> i2t_1; 
    v.emplace_back(i2t_1); 
    Int2Type<1> i2t_2; 
    v.emplace_back(i2t_2); 

    auto x0 = v[0]; 
    auto x1 = v[1]; 

    f(x0.get());    // After my imagination this would have called void f(const Int2Type<0>&) 
    f(x1.get());    // After my imagination this would have called void f(const Int2Type<1>&) 
} 

Ok, so möchte ich die richtige Überlastung von f gewählt werden, dies jedoch nicht kompiliert wie bei der Kompilierung ist nicht bekannt, welche Art x0 und x1 tatsächlich haben. Aber gibt es ein alternatives Design, das dieses Verhalten realisieren kann?

Antwort

0

Überladung ist ein statischer Mechanismus, der auf statischen Typen basiert.

Wenn Sie Verhalten ändern möchten dynamisch basierend auf dem dynamischen Typ eines Objekts, bietet C++ weitere eingebaute Sprache-Funktion für das: Virtuelle Funktionen. Verwenden Sie sie wie folgt aus:

struct Int2TypeBase 
{ 
    virtual void do_f() = 0; 
}; 

template <int v> struct Int2Type : Int2TypeBase 
{ 
    void do_f() override 
    { 
     // specific behaviour for Int2Type<v> goes here 
    } 

    /* ... */ 
}; 

void f(Int2TypeBase & x) { x.do_f(); } 

Jetzt Sie f auf jedem Untergrund subobject und das richtige Verhalten zur Laufzeit ausgewählt aufrufen können. Insbesondere f(x0.get()) und f(x1.get()) wählen und versenden nun zur Laufzeit Int2Type<0>::do_f bzw. Int2Type<1>::do_f.

+0

leider nicht auf meine Situation anwendbar, da in Wirklichkeit die 'f'-Funktionen unterschiedliche Rückgabetypen haben. –

+0

@lotolmencre: Leider hat deine Frage diese neue Anforderung geheim gehalten ... –

+0

ja, ich habe nicht daran gedacht, als ich das minimale Arbeitsbeispiel baute. –

Verwandte Themen