2011-11-03 104 views
6

ISO 98/03標準(14.3.1節)似乎禁止使用具有內部鏈接的類型作爲模板參數。 (請看下面的例子。)C++ 11標準沒有。 G ++ - 使用舊標準 - 允許它。 我誤讀了03標準,還是隻是讓g ++這個幻燈片?內部類型作爲模板參數

namespace 
{ 
    struct hidden { }; 
} 

template<typename T> 
struct S 
{ 
    T t; 
}; 

int main() 
{ 
    S<hidden> s; 
    return 0; 
} 
+0

哪g ++版本?可能是一個擴展 –

回答

7

你是正確的,C++ 03不允許使用一種具有內部鏈接作爲模板類型參數,而C++ 11呢。

但是,我似乎記得,匿名命名空間內的定義仍然有外部鏈接。


燁,第3.5節[basic.link]

具有名稱命名空間範圍(3.3.5)具有如果是

  • 的對象,參考,功能名稱內部連接或明確聲明爲靜態的函數模板,或者明確聲明爲const且既沒有顯式聲明也沒有明確聲明的對象或引用以前也沒有聲明有外部聯繫;或
  • 匿名聯盟的數據成員。

具有命名空間範圍的名稱具有如果是

  • 對象或參考的名稱外部聯動,除非它具有內部連接;或
  • 一個函數,除非它有內部連接;或
  • 一個命名的類(第9條),或在typedef聲明中定義的一個未命名的類,其中該類具有用於鏈接目的的typedef名稱(7.1.3);或
  • 一個命名枚舉(7.2),或在typedef聲明中定義的未命名枚舉,其中枚舉具有用於鏈接目的的typedef名稱(7.1.3);或
  • 屬於具有外部鏈接的枚舉的枚舉器;或
  • 模板,除非它是具有內部鏈接的函數模板(第14節);或
  • 命名空間(7.3),除非它在未命名的命名空間內聲明。

您在名稱空間範圍內有一個命名類,它具有外部鏈接。

而在115頁的底部的註腳ISO/IEC的14882:2003澄清:

雖然具名命名空間的實體可能有外部鏈接,它們是有效地獨有的翻譯名稱限定單位,因此永遠不能從任何其他翻譯單位看到。

如果您有其他版本,請嘗試查看第7.3.1節。1 [namespace.unnamed]

4

這不是規則的有效示例。您示例中的hidden類具有外部鏈接。 (它有一個編譯器生成的惟一名稱,不得將電流轉換單元實際上可以用它連接之外,但它仍然是外部的。)

該標準給出了本地類型的例子:

template <class T> class X { /* ... */ }; 
void f() 
{ 
    struct S { /* ... */ }; 

    X<S> x3; // error: local type used as template-argument 
    X<S*> x4; // error: pointer to local type used as template-argument 
} 
相關問題