簡體   English   中英

在基類=未定義行為之后專門化type_trait?

[英]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 )。 您有幾種方法:

  • 引用它時要對其進行限定:

     public: typename C::typee f(){ return "OK";} 

    [現場示例]

  • 將其帶入您的班級范圍( VTT的回答也建議):

     using typename BT<C<T>, T>::typee; public: typee f(){ return "OK";} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM