2012-05-17 58 views
4

在下面的設置中,我怎樣才能使它可以在派生類Derived<T>內引用名稱Bar如何命名模板化基類中的嵌套模板?

template <typename T> struct Foo 
{ 
    template <typename U> struct Bar { }; 
}; 

template <typename T> struct Derived : Foo<T> 
{ 
    // what goes here? 

    Bar<int> x; // Error: 'Bar' does not name a type 
}; 

我試過using Foo<T>::Bar;,但這並沒有幫助。是否有任何種類的using聲明可以使派生類已知的嵌套基模板的名稱,以便我可以保持簡單的 配給Bar<int> x

我知道我可以說typename Foo<T>::template Bar<int> x;,但我有很多這樣的情況,我不想不必要的冗長冗長的代碼。我也有很多不同的「int s」,因此每個嵌套模板實例的typedef也不可行。

此外,我不能在此時使用GCC 4.7,也不會使用C++ 11,因此會喜歡沒有模板別名的「傳統」解決方案。

回答

6

在C++ 11可以使用別名模板:

template <typename T> struct Derived : Foo<T> 
{ 
    template<typename X> using Bar = typename Foo<T>::template Bar<X>; 
    Bar<int> x; 
}; 

編輯

傳統的解決方案是你已經說了什麼,typename Foo<T>:template Bar<int>,或效仿「模板的typedef 「

template <typename T> struct Derived : Foo<T> 
{ 
    template<typename X> 
    struct Bar 
    { typedef typename Foo<T>::template Bar<X> type; }; 
    typename Bar<int>::type x; 
}; 

將別名模板添加到語言的原因之一是他們支持的事情是不能在C++ 03中容易表達。

+0

是的,的確如此。不幸的是,我沒有對這種編譯器的實際訪問權限,所以如果可能,我想要一個「傳統」解決方案:-S –

+0

@KerrekSB:什麼是「非傳統」的? – Nawaz

+0

@Nawaz:我不能在我需要這個項目的地方使用它:-) –

1

聲明xFoo<T>::Bar<int> x;只適用於我。

+0

我認爲,這不應該工作!如果是這樣,那麼我想知道怎麼回事。也許,編譯器有bug? – Nawaz

+0

@Nawaz:爲什麼?它在Dev-C++ 4.9.9.2中編譯。 – miloszmaki

+0

我不想更改聲明。我真的很想*能夠只說'酒吧 x;'。 –

0

這工作:

template <typename T> struct Foo 
{ 
    template <typename U> struct Bar { }; 
}; 

template <typename T> struct Derived : Foo<T> 
{ 
    template<class W> 
    struct Bar : public Foo<T>::template Bar<W> { 

    }; 

    Bar<int> x; 
}; 

IDK如果這是你在找什麼,但它編譯。

+1

這不完全是一回事。它很接近,但即使類型相同也應該起作用的微不足道的事情在這種情況下不會發生:'派生的 d; Foo :: Bar y; d。x = y;' – cvoinescu

+0

在我的回答中給出了比「template typedef」更好的語法,但值得注意的是'Foo :: Bar '和'Derived :: Bar '實際上並不是同一類型。這可能沒有關係,但它可以在某些情況下例如與'Foo :: Bar'一起工作的模板或重載可能與Derived :: Bar不匹配,所以會使用錯誤的重載。 (編輯:我看到cvoinescu說同樣的事情,但更清楚。) –

+0

@cvoinescu是的,它不起作用。然而,如果這個類只在Derived中內部使用,那麼它將起作用(儘管我不知道這是否是這種情況)。我只想指出比用於聲明模板typedef的語法短的語法。 – mfontanini