[英]specialize type_trait after base class = undefine behavior?
我想讓用戶能夠控制基類的“內部類型”。 此代碼可以正常工作。
版本1 ( 演示 )
//library layer
template<class Derived> class BT_trait{
public: using type=int;
};
template<class Derived> class BT{
public: using typee=typename BT_trait<Derived>::type;
public: typee f(){ return 1;}
};
//user code below
class C;
template<> class BT_trait<C>{
public: using type=std::string; //<-- user want to set "internal type"
};
class C : public BT<C> {
public: typee f(){ return "OK";}
};
int main(){
C bt;
std::cout<< bt.f();
}
如果我通過添加模板參數使其更加復雜,它將不再可編譯。
(如下所示)
版本2 ( 演示 )
template<class Derived> class BT_trait{
public: using type=int;
};
template<class Derived,class Dummy> class BT{
public: using typee=typename BT_trait<Derived>::type;
public: typee f(){ return 1;}
};
//user code below
template<class T> class C;
template<class T> class BT_trait<C<T>>{
public: using type=std::string;
};
template<class T> class C : public BT<C<T>,T> {
// public: typename BT<C<T>, T>::typee f(){ return "OK";} //Version #2b
public: typee f(){ return "OK";} //Version #2a
//^ error: 'typee' does not name a type; did you mean 'wctype'?
};
int main(){
C<int> bt;
std::cout<< bt.f();
}
但是,如果我使用#2b
(臟)而不是#2a
(簡潔),則上面的代碼將正常工作。
為什么? 是否可以使#2a
工作?
[temp.expl.spec]節14.7.3p6:如果模板,成員模板或類模板的成員是顯式專門化的,則應在首次使用該專門化之前聲明該專門化,這將導致隱式實例化在發生這種使用的每個翻譯單元中的位置; 無需診斷。
我懷疑我的代碼是未定義的行為。 正確?
我是模板專業化的新手。
請注意, typee
類型取決於模板參數。 作為選擇,您可以通過使用using指令添加來使typee
可以識別:
using typename BT<C<T>, T>::typee;
public: typee f(){ return "OK";}
不,您的代碼不會顯示UB,即使編譯時也不會。
問題在於,一旦C
成為模板,兩階段查找規則便開始在其中應用。 基本上,在解析模板時會查找不依賴於模板參數的名稱,這時T
的參數當然是未知的,因此編譯器無法查看BT<C<T>, T>
並查找typee
定義的typee
。 所以失敗了。
您必須將typee
標記為從屬名稱(因為它確實取決於T
)。 您有幾種方法:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.