【问题标题】:Undefined reference when using template [duplicate]使用模板时未定义的引用[重复]
【发布时间】:2016-01-25 13:02:33
【问题描述】:

我有一个名为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&lt;unsigned short&gt;(DataHandler&lt;unsigned short&gt;*)

DenseTrafficHandler header 是这样的:

#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&lt;T&gt;

【问题讨论】:

    标签: c++ templates reference compiler-errors


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

      添加到您的 DenseTrafficHandler.cpp

      template class DenseTrafficHandler<unsigned short>;
      
    2. 可以,在头文件中实现即可。阅读更多关于它的信息here

    【讨论】:

    • #2 仅当函数在类主体中声明时才为是。如果 OP 仍然想在类主体之外定义函数,他仍然必须为每个函数使用 template &lt;typename T&gt; DataHandler&lt;T&gt;::functionName()
    • 谢谢,但由于 DenseTrafficHandler 不是模板类,我不能使用这个解决方案(我不想让它成为模板类)。我解决了它,覆盖了构造函数,指定了两种可能的类型(char 和 short)。其实我只需要在DenseTrafficHandler的构造函数中使用模板类DataHandler,所以这个方案更适合我的目的。
    • @rh0x 哎呀,刚刚发现它不是一个模板类,而只是一个模板构造函数,对不起,我不知何故错过了。是的,您必须针对不同类型进行专业化,所以您做对了。我会更新答案。
    猜你喜欢
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多