2015-06-16 43 views
6

從實用的角度來看,我明白無論typedeftest有點「多餘」的需要,如果我們希望下面的代碼編譯被刪除:爲什麼typedef模板非法?

template< typename type_t > 
typedef struct tagTest 
{ 
    int a; 
} test; 

但是,我認爲,這組typedef聲明是聲明集的一個子集。他們碰巧有那個特定的decl-specifier。那是我爲

typedef struct tagTest 
{ 
    int a; 
} test; 

引入標識符test聲明結構tagTest合理化。如果這種解釋是正確的,那麼標準中的以下段落應該允許templatetypedef(儘管不具有關鍵字using給出的含義)。

在模板聲明的聲明應 - (1.1) 聲明或定義一個函數,類,或者一個變量,或 - (1.2) 定義成員函數,一個構件類中,構件枚舉,或一個類 模板的或嵌套類模板內的類的靜態數據成員,或者 - (1.3) 定義一個類或類模板的成員模板,或 - (1.4 ) 是別名聲明。

我在我的推理中看不到錯誤,但結論是非法的。

解決上述難題的標準有哪些相關部分?上述推理


UPDATE 部分使用了typedefstruct聲明結構的事實。據我所知,說明符是指任何聲明的變量都是真正的類型。也就是說,typedeftest從單純的變量升級到與聲明的tagTest等效的類型。這就是爲什麼下面的代碼編譯(雖然有警告)。

typedef struct tagTest 
{ 
    int a; 
}; 
tagTest t; 

其中一個答案照顧多餘的test。但是,它是可以使用的typedef沒有聲明符

+0

呃......這些情況都沒有涵蓋它。聲明恰好包含聲明一個類的東西並不意味着該聲明本身聲明瞭一個類。該聲明僅僅定義了一種類型。 – hvd

+0

@hvd在C中,包含標記結構的typedef確實會聲明該結構,並定義一個名稱來替代它。你是說C++在這方面有所不同嗎? – davmac

+0

@davmac不,我們同意這種聲明的最終效果。我要說的是,聲明結構的部分不是聲明本身,只是聲明的一個子部分。這適用於C和C++。 – hvd

回答

3

Template typedefs不允許預C++ 11和C++ 11 template aliases引入來解決這些問題。 (CFR)。 C++ template typedefswikipedia

因爲,正如你提到的,標準不允許typedef是在那裏,代碼是無效

別名聲明:

using identifier attribute-specifier-seqopt= type-id ; 

typedef聲明也不別名聲明

此外,你不能有一個聲明符,如果你聲明一個類模板,它是明確的標準

[臨時]/P3

在模板中聲明禁止,顯式特化或顯式實例化聲明 中的init聲明符列表最多應包含一個聲明符。 當使用這樣的聲明來聲明類模板時, 不允許聲明者

所以即使沒有下文將編譯

template< typename type_t > 
struct tagTest 
{ 
    int a; 
} test; 

編輯:

據無處指定

typedef struct S { }; 

應該是一個錯誤,從而GCC和鐺接受警告。我認爲鐺上[臨時]/3計數到問題的情況下的typedef正在與模板使用的錯誤,而GCC拒絕該代碼立即

template<typename T> 
typedef struct S { }; 

CFR。鏗鏘小蟲22249

+0

刪除'test'標記但保留'typedef'說明符應該是合法的,因爲這些聲明是可選的。 – Hector

+0

@Hector編輯了這個問題,增加了這個案例的細節 –

+0

+1這個關於clang的鏈接很好。但是關於你的開頭段落,我並不認爲'template typedef struct S {};'應該和'using'關鍵字一樣工作。我認爲該標準允許它與'template struct S {};'具有相同的含義。 – Hector

1

獨立於typedef定義了什麼because「聲明名爲類/結構/聯合或命名枚舉時初始化聲明符列表是可選的」,這是一個typedef聲明,其未在這些情況下所列:

  • [構件]函數
  • [構件]類
  • 可變
  • 構件枚舉
  • 01嵌套類模板中的類或類模板的
  • 成員模板類的類模板/的
  • 靜態數據成員
  • 別名聲明

而僅僅是明確typedef聲明也不別名聲明別名聲明,由語法在標準規定§7是:

別名聲明

using identifier attribute-specifier-seqopt= type-id ;

且不說,如果這是可能的,那麼模板using聲明將不會像今天這樣「酷」,並且there would be little to no sense to have both

+0

我認爲OPs的意思是說文本並不是說聲明必須是一個「[member]類」聲明(在其他類型中),而是它「應聲明或定義」一個類,該類使用struct子聲明可以說是可以的。 – davmac

1

C不支持模板和C++中的

typedef struct tagX { 
} X; 

語法遺蹟C,那裏允許C頭文件等,而不是在實際的C++應用的持續支持。

C++的語法上面是

struct X {}; 

(YMMV上支架放置)