2014-10-10 63 views
2

這些線路都在不同的頭文件,並最終得到包括在下列順序源文件:如何讓這些typedefs工作?

class Alice; 

/* pointers to Alice declared here!! */ 

template<class T> 
class Bob; 

typedef Bob<int> Alice; 

template<class T> 
class Bob 
{ 
}; 

VS2013 error C2371: 'Alice' : redefinition; different basic types

爲什麼這是一個錯誤? 任何方法來解決它?

+0

使用不同的名稱空間? – ForEveR 2014-10-10 10:23:59

+0

@ForEveR這是一個建議或問題? – 2014-10-10 10:30:28

+0

第一個Alice是一個類,第二個Alice是一個模板。可能這就是它拋出錯誤的原因。我的問題是爲什麼你需要這種類型的定義。你可以重命名Alice的任何一個。 – user966379 2014-10-10 10:33:51

回答

3

這是不合適的聲明爲一個類和一個不同類的typedef。儘管類名和typedef名在許多情況下是可以互換的,但並不總是,例如當類是Aliceclass Alice(使用所謂的詳細類型說明符)時,可能指的是類,但如果Alice是typedef名稱,則該類型無效。該規則始於C,在那裏你只能使用使用詳細說明類型說明符,並且必須聲明一個單獨的typedef才能簡單地說出Alice

區別很重要,因爲該類型有一個「名稱用於鏈接目的」,它是用於名稱綁定的名稱,它影響鏈接器看到的符號。

如果一個文件只看到了typedef名稱Alice和使用,對於重整的函數名稱,如void foo(Alice*)那麼你就不能說功能與其他引用鏈接到void foo(Bob<int>*)即使它們應該具有相同的重整名稱。

因此,編譯器必須區分類型定義(它們只是別名)和類型的「真實名稱」(即它的名稱用於鏈接目的)。

唯一的解決方法是正確聲明的類型,這樣的Alice作爲一個typedef聲明使用無處不在,即以取代不真實class Alice;聲明:

template<class T> class Bob; 
typedef Bob<int> Alice; 
+0

嗨,謝謝。有沒有解決辦法? – 2014-10-10 10:35:38

+0

template class Bob {}; typedef Bob Alice; – Clearer 2014-10-10 10:40:04

+1

@Clearer,你不需要定義'Bob'爲了能夠聲明'Alice' typedef,你只需要聲明它。 – 2014-10-10 10:41:10

1

您可以使用繼承作爲一個可能的解決方法:

class Alice; 

Alice* a1; 

template<typename T> 
class Bob {}; 

class Alice : public Bob<int> {} ; 
0

如果我認爲這是正確的,有說法

Alice obj; 

編譯器如何解釋「Alice」。在符號表中會有2個條目:一個作爲一個類,另一個作爲模板。

這就是爲什麼它給錯誤。