2016-04-04 25 views
0

Ich habe eine Klasse B, die von A ergibt sich:Wie kann ich den Datentyp zur Laufzeit in C++ ermitteln?

template<class T> 
class A 
{ 
    class iterator; // Defined fully 

    iterator begin() 
    { 
     // Returns a pointer to the first element 
    } 
    iterator end() 
    { 
     // Returns a pointer to the last element 
    } 
} 
template <class T> 
class B : public A 
{ 
    // It automatically inherits the iterator 
} 

template <typename InputIterator> 
void foo (InputIterator first,InputIterator last) 
{ 
    // Some code to infer whether it is of type A or B 
} 

Jetzt sind einige Funktion sagen foo()B::begin() auf einmal mit und einmal mit A::begin() genannt wird.

Ich muss während der Laufzeit den Typ bestimmen, um den Typ abzuleiten und einige Flag-Variablen zu setzen. Wie mache ich das? Ich habe versucht, typeinfo() zu verwenden, aber es gibt den gleichen Wert für beide Iteratoren zurück.

+0

Nicht sicher, was Sie fragen. Sie haben 'InputIterator' - das ist schon der Typ. Beide Iteratoren * sind * vom selben Typ. Fragen Sie, wie man "B :: iterator" von "A :: iterator" unterscheidet? – Barry

+0

Wenn Sie auf verschiedenen Typen unterschiedlichen Code ausführen müssen, warum nicht zwei Überladungen machen, die tun, was benötigt wird, und dann eine allgemeine Funktion aufrufen? – NathanOliver

+0

Ich muss ableiten, ob das übergebene Argument ist von A :: Iterator oder B :: Iterator – PRP

Antwort

1

Von der Bibliothek type_traits können Sie eine Art Magie verwenden:
is_base_of - gibt true zurück, wenn Base die Basis von Derived ist.
is_same - wahr, wenn A die gleiche Art wie B.
Alles mit type_traits ist hier http://www.cplusplus.com/reference/type_traits/?kw=type_traits

gefunden werden können Sie nicht so Laufzeit sind, ist es nur einige Magie mit structs und Vorlagen, C++ nicht unterstützt Typ als Daten standardmäßig. Wenn Sie möchten, können Sie Boost-Bibliothek verwenden, unterstützt Typen wie ich weiß.

UPD:
Als Kommentare unter der Frage erwähnt A :: Iterator ist absolut identisch mit B :: Iterator, also ohne Blick auf Klassen sind sie die gleichen Speicher Chunk.
So Lösung (vielleicht) etwas andere Funktion zu schaffen, was eigentlich auf Klassen abhängt:

template <typename LeftClass, typename RightClass> 
void foo (LeftClass left, RightClass right) 
{ 
    if(is_same<LeftClass, RightClass>::value) 
    { 

    } 
//Or that 
    if(is_same<LeftClass, A>::value && is_same<RightClass, A>::value) 
} 

Nur nicht vergessen, diesen „Freund“ mit Klassen zu machen.

+0

Das Problem ist, dass in 'foo (...)' gibt es kein 'A' oder' B' gibt es nur 'InputIterator' – vu1p3n0x

+0

Ow ... Nun, es gibt auch is_convertible oder is_same ... Scheint, ich kann immer noch kaum verstehe die Frage. –

0

typeinfo() gibt den gleichen Wert, da beide A::begin() und B::begin() geben Sie einen Wert des gleichen Typs.

sollten Sie entweder B::iterator vererben A::iterator oder eine spezielle Funktion in Ihrem Iterator haben, die einen Verweis/Zeiger gibt es Container ist (die dann entweder vom Typ A oder geben B).

Verwandte Themen