使用模板时未定义的引用

时间:2016-01-25 13:02:33

标签: c++ templates reference compiler-errors

我有模板化类,名为 DataHandler

#ifndef DATAHANDLER_H
#define DATAHANDLER_H
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <set>
#include "constants.h"

template <typename T>
using Car = std::pair< T, T>;

template <typename T>
using SparseMatrix = std::vector< Car<T> >;

template <class T>
class DataHandler
{

    public:
        // initializes a new DataHandler only if none has been created,
        // otherwise return the living instance
        static DataHandler<T>* getInstance()
        {
            if(!dataHandler)
                dataHandler = new DataHandler();
            return dataHandler;
        }

        void readFile();

        SparseMatrix<T>* getSparseBlue(){ return &sparseBlue; }
        SparseMatrix<T>* getSparseRed(){ return &sparseRed; }
        virtual ~DataHandler();

    private:
        // static DataHandler to ensure only one instance can be created
        static DataHandler<T> *dataHandler;

        // private constructor to use DataHandler as a Singleton
        DataHandler();

        int numElem = 0;
        int m_rows, m_cols = -1;


#endif // DATAHANDLER_H

来源文件是:

#include "data_handler.h"
#include <fstream>
#include <algorithm>
#include <omp.h>
#include <chrono>

using namespace std;
using namespace constants;

// Global static pointer used to ensure a single instance of the class.
template<typename T>
DataHandler<T>* DataHandler<T>::dataHandler = NULL;

template<typename T>
DataHandler<T>::DataHandler()
{
//ctor
}

template<typename T>
DataHandler<T>::~DataHandler()
{
//dtor
}

template<typename T>
void DataHandler<T>::readFile()
{
   // do some stuff
}

// Instantiation of relevant templates
template class DataHandler<unsigned char>;
template class DataHandler<unsigned short int>;

在最后两行中,我实例化了我在main.cpp中定义的模板:

#include <iostream>
#include <chrono>
#include <fstream>
#include <algorithm>

#include "data_handler.h"
#include "dense_traffic_handler.h"
#include "sparse_traffic_handler.h"
#include "constants.h"

using namespace std;   

// Check the number of rows/cols to choose between char or short int for the sparse case
bool matrixIsSmall()
{    
    return true;
}
void integerCase()
{
    typedef unsigned char T;
    DataHandler<T> *dh = DataHandler<T>::getInstance();
    dh->readFile();

    DenseTrafficHandler dth(dh);    // ****** ERROR HERE *****
}

void charCase()
{
    typedef unsigned char T;
    DataHandler<T> *dh = DataHandler<T>::getInstance();
    dh->readFile();

    DenseTrafficHandler dth(dh);    // ****** ERROR HERE *****
    SparseTrafficHandler<T> sth;

    set<unsigned short int> step = dh->getstep();

    int currentStep = 0;
    set<unsigned short int>::const_iterator stepToSave = step.begin();
}

int main(int argc, char *argv[])
{
    if(matrixIsSmall())
        charCase();
    else
        integerCase();

    return 0;
}

编译器给我一个错误: undefined reference to DenseTrafficHandler::DenseTrafficHandler<unsigned short>(DataHandler<unsigned short>*)

DenseTrafficHandler 标题就是这样:

#ifndef TRAFFICHANDLER_H
#define TRAFFICHANDLER_H

#include "constants.h"
#include "data_handler.h"

class DenseTrafficHandler
{
    public:
        template<typename T>
        DenseTrafficHandler(DataHandler<T> *dh);
        virtual ~DenseTrafficHandler();
    private:
        int m_cols, m_rows;
        char* data;
        char ** dense = NULL;
};

#endif // TRAFFICHANDLER_H

DenseTrafficHandler 来源是:

#include "dense_traffic_handler.h"

using namespace std;
using namespace constants;

template <typename T>
DenseTrafficHandler::DenseTrafficHandler(DataHandler<T> *datah)
{
    DataHandler<T> *dh = datah;
    dense = dh->getDense();
    m_rows = dh->getm_rows();
    m_cols = dh->getm_cols();
}
DenseTrafficHandler::~DenseTrafficHandler()
{
    //dtor
}

所以我有两个问题:

  1. 为什么我会收到此错误以及如何管理?
  2. DataHandler源中是否有一种方法未指定 每项功能template <typename T> DataHandler<T>::functionName()? (我的意思是using namespace Datahandler<T>

1 个答案:

答案 0 :(得分:1)

  1. 您收到此错误,因为编译器未生成此模板类型的代码。解决方案之一是告诉编译器通过模板实例化显式执行此操作:

    添加到 DenseTrafficHandler.cpp

    template class DenseTrafficHandler<unsigned short>;
    
  2. 是的,只需在头文件中实现它。阅读更多相关信息here