2016-04-01 27 views
1

Bu sorunun C++ şablonları ile şaşırıyorum.İç içe geçmiş C++ şablonlarında başvuru türü

Bir sınıf aşağıda tanımlanmıştır:

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 
}; 

DataConsumer şablon bir tür DataSource sürmesi bekleniyor. DataSource kendisi karmaşık bir türüdür; o da başka bir parametre ile şablon alındığı anlamına gelir:

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 
}; 

Benim sorun budur: Ben DataConsumer sınıf DataSource nesnesi altında yatan şablon parametresi sorgulamak istiyorum. Örneğin, Bu kod ön çalışıyor:

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

kişinin gerekli sözdizimi ile bana yardım edebilir:

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

Ne istiyorum gerçekten tip getCurrentDataFrame() tarafından döndürülen elde etmektir?

+1

'INSERT_TYPE_HERE * frame = getCurrentDataFrame();' - bu "çalışma" örneğinizde olduğu gibi "dataSource-> getCurrentDataFrame(); olması gerekiyordu? – WhozCraig

+0

Hayır; Bu tam olarak benim sorum. Her zaman dataSource-> getCurrentDataFrame() yazmayı değil, yerel bir değişken bildirmek istiyorum. – Lancophone

+0

Şablon parametresi türünü temsil eden DataSource içinde bir yazım hatası bildirebilirsiniz (tip özellikleri tekniklerini). Veya C++ 11'de bir 'decltype' yapısı kullanılırsa. Ayrıca 'tüketme' yöntemini şablonlandırabilir ve şablon parametresini yakalayabilirsiniz. –

cevap

0

Eğer sadece işlev çağrınızın geri dönüşünü yakalamak istiyorsanız:

template <class T> DataSource { 
}; 
template <class T> DataConsumer { 
public: 
    void consume(T *arg) { 
     auto local_var = arg->getCurrentFrame(); 
     ... 
    } 
}; 
+0

En bilgilendirici olanı olarak bunu cevap olarak seçti – Lancophone

0
INSERT_TYPE_HERE * frame = getCurrentDataFrame(); 

Belki otomatik kullan?

auto frame = getCurrentDataFrame(); 

"type_traits" tekniği temel olarak public typedefs'e sahiptir. Böyle bir şey:

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

Genellikle biri kendi temel tipi ve bağımlı tip

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 
    // ..... 

ve c kullanabilirsiniz eğer

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? 
} 

da DataConsumer kodunda daha diğer ad şablonu içinde typedef yaratır ++ 11 standradyerine @Phantom puanları gibi bir auto anahtar sözcüğünü kullanabilirsiniz.

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

C++ 11 decltype İle: şablon üye fonksiyonu ile

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

:

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

Ayrıca C++ 11 otomatik kullanabilirsiniz tip özellikleri ile

+0

da C++ 11'i kullanabiliyorsa, 'typedef' yerine' using 'kullanabilirdi :) – kfsone

İlgili konular