2013-10-31 172 views
0

我使用以下代碼從文件加載對象(對象的子類A,B和C)。編譯問題我是從loadObjFromLine使用不帶模板參數的模板化函數

load.h:611:33: erreur: there are no arguments to ‘loadObjFromLine’ that depend on a template parameter, so a declaration of ‘loadObjFromLine’ must be available [-fpermissive] 
load.h:611:33: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated) 

當我使用pObj = loadObjFromLine<T>(line);,我得到

load.h: In function ‘bool loadObjects(const string&, Object<T>*&)’: 
load.h:611:13: erreur: ‘loadObjFromLine’ was not declared in this scope 
load.h:611:30: erreur: expected primary-expression before ‘>’ token 

編輯 我知道我可以使用loadObjFromLine<double>但我想的類型T是在loadObject中使用相同(Object * &)。也許這不是正確的做法..

任何想法?

template<typename T> 
Object<T>* loadObjFromLine(const std::string& line) 
{ 
    std::stringstream lineStream(line); 
    int objType(-1); 
    lineStream >> objType; 

    Object<T> *pObj = NULL; 

    if (objType == 0) 
    { 
     A<T> *pO = new A<T>; 
     if (lineStream >> *pO) 
      pObj = pO; 
    } 
    else if (objType == 1) 
    { 
     B<T> *pO = new B<T>; 
     if (lineStream >> *pO) 
      pObj = pO; 
    } 
    else if (objType == 2) 
    { 
     C<T> *pO = new C<T>; 
     if (lineStream >> *pO) 
      pObj = pO; 
    } 

    return pObj; 
} 

template <typename T> 
bool loadObjects( const std::string &filename, Object<T>*& pObj) 
{ 
    std::ifstream fileStream(filename.c_str()); 
    if (fileStream.good()) 
    { 
     std::string line; 
     int objType; 

     // Loading boundary. 
     while(std::getline(fileStream, line)) 
     { 
      pObj = loadObjFromLine(line); 
//   pObj = loadObjFromLine<T>(line); 
      if (!pObj) 
       return false; 
     } 
     fileStream.close(); 
     return true; 
    } 
    return false; 
} 
+0

pObj = loadObjFromLine (line);'?它乾淨清晰。德國的答案中提供的解決方案不能被推薦(見評論)。 – Walter

+0

@Walter,正如我的文章所述,它不會編譯。也許我錯過了什麼,但是什麼? – user2287453

+0

@Walter,好吧,如果我把loadObjFromLine()放在loadObject()之前,它就可以工作......這是爲了這裏,它不在我的代碼中... – user2287453

回答

0

這樣做:

LoadObjFromLine<Type>(line); 

正如你所看到的,是一個字符串參數和模板參數:

template <class T> 
Obj<T> * LoadObjFromLine(std::string const & line); 

不能推導出的參數。爲了推導參數,簽名應該是這樣的(注意,我也將返回類型更改爲void)。

template <class Obj> 
void LoadObjFromLine(std::string const & line, Obj * obj); 

這種方式,你可以這樣做:

Obj<MyType> * obj; 
LoadObjFromLine(line, obj); 

而且OBJ將被推出。

在你的情況下,沒有參數傳遞到函數以推導出T模板參數。

編輯:如下所述,LoadObjFromLine的首選簽名將是您的程序中使用的簽名,而不是使用void作爲返回類型的簽名。 帶有無效簽名的示例僅用於說明何時可以推導出模板參數,以及何時無法推導出模板參數

+1

我不敢相信我沒有想到它。 。 謝謝。 – user2287453

+0

將指針'Obj * pObj'作爲參數傳遞,以便可以推導出該類型是**錯誤的動機**。乾淨的方式是返回指針,如原始代碼(並給出類型''),因爲從那裏指針'pObj'被分配是顯而易見的。 – Walter

+0

這只是爲了說明的目的,以明確爲什麼參數不能被推斷。我發現這個簽名比較說明了爲什麼可以推導出一個,而另一個版本不能。我同意最好的方法是明確地給出模板參數。 –

0

您需要指定類型loadObjFromLine應該明確實例化,例如:loadObjFromLine<T>("hgjghgj")

編譯器的錯誤消息在這種情況下非常有用:編譯器無法推斷出它應該實例化函數的類型(因爲它不依賴於函數的參數),因此您需要明確說明它。