2016-04-01 5 views
1

Ich bin von diesem Problem mit C++ - Vorlagen verwirrt.Referenzieren Typ in verschachtelten C++ - Vorlagen

Ich habe eine Klasse weiter unten definiert:

template <class T> 
class DataConsumer 
{ 
public: 

    DataConsumer() : processCount(0) 
    {} 

    ~DataConsumer() 
    {} 

    // Sub classes override this in order to do their thing 
    void preConsume() 
    { 
     std::cout << "Preconsume called" << std::endl; 
     processCount++; 
    } 

    virtual void consume(const T *dataSource) 
    { 
     preConsume(); 
    } 

private: 

    long long processCount; // The bare bones template keeps track of the number of data frames it has consumed 
}; 

Die DataConsumer Vorlage einen Typ Datasource zu übernehmen soll. DataSource ist selbst ein komplexer Typ;

template <class T> 
class DataSource 
{ 
public: 

    // C-tor and D-tor 
    DataSource() : currentFrame(new T) 
    {} 

    // Note that this is a weak assignment as the data 
    // is not copied; the pointers are merely set to the 
    // existing frames properties 
    DataSource(T& existingFrame) : currentFrame(new T) 
    { 
     currentFrame->frame = existingFrame.frame; 
     currentFrame->meta = existingFrame.meta; 
    } 

    ~DataSource() 
    {} 

    // Update function. Specializations expand on this 
    void update() 
    {} 

    // Return a const pointer to something (the data source can be an image frame, textual, binary etc.) 
    const T * getCurrentDataFrame() const 
    { 
     const T * const frame_ptr = currentFrame.get(); // Just return an unmodifiable pointer 
     return frame_ptr; 
    } 

    void echo() 
    { 
     // Generic data source just prints its current frame 
     std::cout << currentFrame->frame << currentFrame->meta << std::endl; 
    } 

private: 

    boost::shared_ptr<T> currentFrame; // The actual data frame object 
}; 

Mein Problem ist folgendes: es ist auch mit einem anderen Parameter als Templat Bedeutung Ich möchte in die DataConsumer Klasse die zugrunde liegende Template-Parameter des Datasource-Objekt abzufragen. Zum Beispiel arbeitet der Code-Snippet fein:

virtual void consume(const T *dataSource) 
    { 
     preConsume(); 
     std::cout << dataSource->getCurrentDataFrame()->toString() << std::endl; // This WORKS! 
    } 

Was will ich wirklich, ist die Art zurück von getCurrentDataFrame() erhalten wird:

virtual void consume(const T *dataSource) 
    { 
     preConsume(); 
     INSERT_TYPE_HERE * frame = getCurrentDataFrame(); 
     std::cout << frame->toString() << std::endl; // How do I do this? 
    } 

Kann mir jemand bitte helfen Sie mit der Syntax erforderlich?

+1

'INSERT_TYPE_HERE * frame = getCurrentDataFrame();' - sollte das 'dataSource-> getCurrentDataFrame();' wie in Ihrem "Arbeits" -Beispiel sein? – WhozCraig

+0

Nein; Das ist genau meine Frage. Ich möchte eine lokale Variable deklarieren, anstatt jedes Mal dataSource-> getCurrentDataFrame() zu schreiben. – Lancophone

+0

Sie können in der DataSource einen typedef deklarieren, der den Vorlagenparametertyp darstellt (types technics). Oder wenn in C++ 11 ein 'declltype'-Konstrukt verwendet wird. Sie können auch die 'consume'-Methode erstellen und den Template-Parameter abfangen. –

Antwort

0

Mit Typ Züge:

template <class T> DataSource { 
public: 
    typedef T element_type; 
}; 
template <class T> DataConsumer { 
public: 
    void consume(T *arg) { 
     typename T::element_type local_var; 
     ... 
    } 
}; 

Mit C++ 11 decltype:

template <class T> DataSource { 
}; 
template <class T> DataConsumer { 
public: 
    void consume(T *arg) { 
     decltype(arg->getCurrentDataFrame()) local_var; 
     ... 
    } 
}; 

Mit Funktionsvorlage Mitglied:

template <class T> DataSource { 
}; 
template <class T> DataConsumer { 
public: 
    template <class X> void consume(DataSource<X> *arg) { 
     X local_var; 
     ... 
    } 
}; 

Sie können auch C++ 11 Auto verwenden Wenn Sie nur die Rückkehr Ihrer Funktion abfangen wollen, rufen Sie an:

+0

Wählen Sie dies als die Antwort, da es die informativste ist – Lancophone

0
INSERT_TYPE_HERE * frame = getCurrentDataFrame(); 

Vielleicht Auto verwenden?

Die "type_traits" -Technik hat grundsätzlich öffentliche typedefs. Etwas wie folgt aus:

template<typename T> 
struct DataFrame { }; 

template<typename T> 
class DataSource 
{ 
    public:   
     typedef DataFrame<T> frame_type; 
     //using frame_type = DataFrame<T>; // c++11 
}; 

template<typename T> 
virtual void consume(const T *dataSource) // imagine T is DataSource 
{ 
    preConsume(); 
    T::frame_type * frame = getCurrentDataFrame(); 
    std::cout << frame->toString() << std::endl; // How do I do this? 
} 
0

Normalerweise ein typedef innerhalb Vorlage erstellt ihr zugrunde liegenden Art und abhängige Arten

template <class T> 
class DataSource 
{ 
public: 
    typedef T value_type; 
    typedef value_type const * pointer_to_const_type; 
    // .... 
    // Return a const pointer to something (the data source can be an image frame, textual, binary etc.) 
    pointer_to_const_type getCurrentDataFrame() const 
    // ..... 

und als in DataConsumer Code alias

template <class T> 
class DataConsumer 
{ 
public: 
    typedef T value_type; 

virtual void consume(const DataSource<T> *dataSource) 
{ 
    preConsume(); 
    typename DataSource<T>::pointer_to_const_type frame = getCurrentDataFrame(); 
    std::cout << frame->toString() << std::endl; // How do I do this? 
} 

auch, wenn Sie c verwenden können ++ 11 Standard Sie können ein Schlüsselwort anstelle von typename DataSource<T>::pointer_to_const_type als @Phantom-Punkte bereits verwenden.

+0

auch, wenn er C++ 11 verwenden kann, könnte er 'using' anstelle von' typedef' verwenden :) – kfsone