2009-07-01 133 views
9

有誰知道爲什麼使用聲明似乎不適用於從依賴基類導入類型名稱?它們用於成員變量和函數,但至少在GCC 4.3中,它們似乎被忽略了。從依賴基類訪問類型

template <class T> 
struct Base 
{ 
    typedef T value_type; 
}; 

template <class T> 
struct Derived : Base<T> 
{ 
    // Version 1: error on conforming compilers 
    value_type get(); 

    // Version 2: OK, but unwieldy for repeated references 
    typename Base<T>::value_type get(); 

    // Version 3: OK, but unwieldy for many types or deep inheritance 
    typedef typename Base<T>::value_type value_type; 
    value_type get(); 

    // Version 4: why doesn't this work? 
    using typename Base<T>::value_type; 
    value_type get(); // GCC: `value_type' is not a type 
}; 

我有一組分配器風格的類型定義,我想整個產業的幾個層次繼承的基類。目前爲止我發現的最佳解決方案是上面的版本3,但我很好奇爲什麼版本4似乎不起作用。 GCC接受使用聲明,但似乎忽略它。

我檢查了C++標準C++ Prog。郎。第3版。 [Stroustrup]和C++模板[Vandevoorde,Josuttis],但似乎沒有解決使用聲明是否可以應用於依賴基類的類型。

如果有助於在GCC郵件列表中看到另一個示例here is the same question being asked,但沒有真正回答。提問者表示他在其他地方見過'使用typename',但GCC似乎不支持它。我沒有其他符合要求的編譯器可用來測試它。

+0

發佈一些代碼,應該編譯(在您的意見)符合編譯器,但沒有。併發布你如何使用模板。 – 2009-07-01 20:21:36

+0

我相信所有相關信息都在上面。版本1-4在MSVC 9上工作,MSVC 9具有不合格的單階段名稱解析(即在實例化時間)。只有版本2和3在GCC 4.3上工作。我不知道任何理由版本4應該是無效的,但GCC不會接受它。 至於用法,它是如何實例化並不重要。我只是試圖讓模板聲明來編譯。上面的代碼是一個更復雜的容器適配器的簡化。 – 2009-07-01 20:57:07

+0

在這裏發佈代碼時,不要期望人們必須編輯它才能編譯它。 – 2009-07-01 21:25:50

回答

8

正如理查德·戈登指出,這一問題是在C++ Standard Core Language Defect Reports 2003年的標準被批准後處理:How do the keywords typename/template interact with using-declarations?

建議作出的決議(2003年4月, 修訂後的2003年10月):

添加新 7.3.3 [namespace.udecl]:

如果使用聲明使用 關鍵字typename並指定 從屬名稱(14.7.2 [temp.dep]), 使用聲明引入的名稱被視爲 typedef-name(7.1.3 [dcl.typedef])。

本文似乎並沒有從10月15日在第二版標準的出現,2003年

GCC還沒有執行這項決議,在bug 14258解釋說:

- -----評論#3來自Giovanni Bajo 2004-02-27 12:47 [回覆] ------- 的問題是我們的USING_DECL沒有 記錄「typename」,那就是 事實上它是通過它導入的類型 。我相信,這用於工作 感謝隱式類型名稱 擴展名。

重複bug 21484表示「使用typename」適用於Comeau和Intel編譯器。由於MSVC將所有名稱視爲依賴項,因此該編譯器不需要(但允許)該構造。


Fixed在GCC 4。7 2011年12月13日!

-1

在聲明base :: value_type的typedef之前,您沒有在Base的模板中包含訪問說明符(public/protected/private)。因此,它默認爲私有,並且不能從派生自Base的類中訪問。