2016-01-25 120 views
0

時,我有一個模板類命名的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
  1. 您收到此錯誤,因爲編譯器不產生這種模板類型的代碼。一個解決方案是爲了告訴編譯器通過模板實例明確地做到這一點:

    添加到您的DenseTrafficHandler.cpp

    template class DenseTrafficHandler<unsigned short>; 
    
  2. 是的,只是實現它在頭文件。閱讀更多關於它的信息here

+1

只有在函數是在類體中聲明的時候,是的。如果OP仍然想要在類體外定義函數,他仍然需要爲每個函數使用'template DataHandler :: functionName()'。 – NathanOliver

+0

謝謝,但由於DenseTrafficHandler不是一個模板類,我不能使用這個解決方案(我不想讓它成爲一個模板類)。我解決了它覆蓋構造函數,指定了兩種可能的類型(char和short)。事實上,我只需要在DenseTrafficHandler的構造函數中使用模板類DataHandler,所以這個解決方案對我而言更好。 – rh0x

+0

@ rh0x糟糕,剛發現它不是一個模板類,而只是一個模板構造函數,對不起,我錯過了某種方式。是的,你必須爲不同類型進行專業化,所以你做對了。我會更新答案。 –