2015-06-24 38 views
7

根據這些定義什麼時候可以在私有成員類型上專門化模板?

template<class T> class foo {}; 
template<class T> class foo1 { static int i; }; 
class bar { class baz {}; }; 

我很驚訝地看到,這個編譯

template<> 
class foo<bar::baz> {}; 

但這種失敗,出現錯誤'class bar::baz' is private

template<> 
int foo1<bar::baz>::i = 42; 

當發生這種情況,並且有一種解決方法,而不是公開類型?

+0

* *很有趣。我得到這是定義這個類的變量的錯誤。即,'foo {};'是好的(g ++),但是'foo f;'不是。所以它幾乎是一個不可用的類型,看起來錯誤只是相對較晚(即不在類定義)。 –

+0

@AmiTavory這是不可用的,因爲你總是可以添加[公共類型別名](http://coliru.stacked-crooked.com/a/22807544d8414c4e)。有趣的問題,雖然。爲什麼在':: i'的專業化方面有訪問檢查? –

+0

@DanielFrey我的理解是,問題是關於沒有修改'bar'代碼的情況。 –

回答

5

考慮CWG #182

某些訪問檢查是在明確的實例抑制。 14.7.2 [temp.explicit]第8段說[...]我很驚訝類似的措詞不存在(我可以找到)專門的 專業化。我認爲這兩種情況應該在下面的例子中等效地處理 (即應該允許專業化 )。

template <class T> struct C { 
    void f(); 
    void g(); 
}; 

template <class T> void C<T>::f(){} 
template <class T> void C<T>::g(){} 

class A { 
    class B {}; 
    void f(); 
}; 

template void C<A::B>::f(); // okay 
template <> void C<A::B>::g(); // error - A::B inaccessible 

[...]

依據(2002年10月)

我們重新考慮這一決定,這兩個 例(明確的分工和明確的實例化)之間的區別是 合適。訪問規則有時會在必要時彎曲,以允許命名某些內容,如顯式實例化,但明確的專門化不僅需要命名該實體,還需要在某處提供一個定義 。

GCC和鏘確實拒絕所示的例子中的最後一行,這是 - 很明顯 - 不一致的行爲,作爲一類模板的相應明確的分工,他們不發出錯誤消息:

template <class> struct T { 
    void g(); 
}; 

class A { class B; class C; }; 

template <> struct T<A::B>; // Ok 
template <> void T<A::C>::g(); // Error 

Demo。所以,我將在這裏走出去的肢體和§14.3/ 3叫你表現出病態的兩種情況:

一個模板參數的名稱應易於在點 它在哪裏用作模板參數

相關問題