如何使用模板函数

时间:2017-03-28 21:02:42

标签: c++ class templates

据我所知,有关于在类模板中初始化静态变量的文章。但是,我使用带有成员函数模板的普通类,所以我不得不问。

在简短版本(不是全班定义)中,我有一个看起来像这样的类:

class BatchManager
{
    private:

        static std::vector<BaseBatch_P> _BATCHES;

    public:

        template <class T>
        static void placeData(T* data){

            //Loop through the entire container
            for (auto&& b: _BATCHES)
                if (b==data){
                    dynamic_cast<Batch<T>>(b)->draw(data);
                }

            //If no bach found, create a new One
            createNewBatch(data);
        }
};

但是,当我想访问函数内的成员变量时,它显示: 对BatchManager的未定义引用:: _ BATCHES

然后我尝试了以下内容:在类标题中保留定义:

 //BatchManager.h

 template <typename T>
 static void placeData(T* data);

cpp 档案:

std::map<GLuint,BaseBatch_P> BatchManager::_TEXTURE_MAP;

template <typename T>
void BatchManager::placeData(T* data){

    //Loop through the entire container
    for (auto&& b: _BATCHES)
        if (b==data){
            dynamic_cast<Batch<T>>(b)->draw(data);
        }

    //If no bach found, create a new One
    createNewBatch(data);
}

它解决了第一个问题,但是又出现了另一个问题,当我想从程序中调用我的静态函数时会发生这种情况:

BatchManager::render(_data);

错误消息如下所示:

undefined reference to BatchManager::placeData<DataType>(DataType*)

我该如何解决这个问题?或者我做错了什么?

1 个答案:

答案 0 :(得分:1)

这样的事情:

#include <vector>
#include <typeinfo>

struct BaseBatch {

    virtual const std::type_info& get_type() const = 0;
    virtual ~BaseBatch() = default;
};

template<class T>
struct Batch : BaseBatch
{

    const std::type_info& get_type() const override
    {
        return typeid(T);
    }

    void draw(T* data) {}
};

using BaseBatch_P = BaseBatch*;

class BatchManager
{
private:

    static std::vector<BaseBatch_P>& get_batches() {
        static std::vector<BaseBatch_P> _;
        return _;
    }

public:

    template <class T>
    static void placeData(T* data){

        //Loop through the entire container
        bool found = false;
        for (auto&& b: get_batches())
            if (b->get_type() == typeid(T)) {
                dynamic_cast<Batch<T>*>(b)->draw(data);
                found = true;
            }

        //If no bach found, create a new One
        if (not found) {
            get_batches().push_back(new Batch<T>);
        }
    }
};