引用嵌套C ++模板中的类型

时间:2016-04-01 16:37:49

标签: c++ templates inheritance syntax

我对C ++模板的这个问题感到困惑。

我有一个定义如下的课程:

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模板应该采用DataSource类型。 DataSource本身就是一个复杂的类型;意思是它也用另一个参数模板化:

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

我的问题是:我想查询DataConsumer类中的DataSource对象的基础模板参数。例如,这段代码可以正常工作:

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

我真正想要的是获取getCurrentDataFrame()返回的类型:

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

有人可以帮我解释一下所需的语法吗?

3 个答案:

答案 0 :(得分:0)

    INSERT_TYPE_HERE * frame = getCurrentDataFrame();

也许使用自动?

    auto frame = getCurrentDataFrame();

&#34; type_traits&#34;技术基本上具有公共typedef。像这样:

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

答案 1 :(得分:0)

通常一个人在模板中创建typedef来为其基础类型和依赖类型别名

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

而不是DataConsumer代码

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

如果您可以使用c ++ 11 standrad,则可以使用auto关键字代替typename DataSource<T>::pointer_to_const_type作为@Phantom点。

答案 2 :(得分:0)

使用类型特征:

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:

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

如果您只想捕获函数调用的返回值,也可以使用C ++ 11 auto:

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