2017-08-25 9 views
3

テンプレートパラメータの型定義のデストラクタを呼び出します。C++は:明示的に私は、次のしている

修飾型はデストラクタの名前と一致しないことを言って、

template <typename X> struct A { 
    typedef X _X; 
}; 

template <typename Y> struct B { // Y is struct A 
    typename Y::_X x; 
    void call_destructor() { 
     x.~Y::_X(); // This doesn't work 
     x.Y::~_X(); // This as well 
    } 
}; 

コンパイルしない

コールの前にキーワードtypenameを使用しても機能しません。ただし、次のコンパイルを行います。

template <typename Y> struct B { 
    typename Y::_X x; 
    typedef typename Y::_X __X; 
    void call_destructor() { 
     x.~__X(); // This works 
    } 
}; 

誰かが理由を私に説明し、typedefせずに行うようにするどのような方法がありますができますか?

template <typename X> struct A { 
    typedef X _X; 
}; 

template <typename Y> struct B { // Y is struct A 
    typename Y::_X x; 
    void call_destructor() { 
     x.Y::_X::~_X(); // This as well 
    } 
}; 


int main(){ 
    B<A<int> > b; 
    b.call_destructor(); 
} 

答えて

2
x.~Y::_X(); // This doesn't work 

は、私は、コンパイラがで_Xを呼び出すと、それを解析すると信じて、構文エラーです:

4

次の罰金私のためにコンパイル

x.Y::_X::~_X() 

を使用して、異なるデストラクタを呼び出す必要があります~Y

もう1つ失敗するのはもう少し面白いです。

あなたが修飾子(::)と†デストラクタを呼び出すと、名前が

x.Y::~_X(); 

を意味し、前の修飾子は中に存在する範囲から見上げているがスコープ内名前_Xを検索しますここではYが存在し、この場合はグローバルスコープです。グローバルスコープには_Xが存在しないため、ルックアップは失敗します。

x.Y::_X::~_X(); 

Yの範囲である第一_Xが常駐スコープ、第二_Xを検索し、ひいては右デストラクタを見出します。

デストラクタの呼び出しを忘れ書き込みと-する最も簡単な方法は、単に

x.~decltype(x)(); 

ですが、gccとMSVCはこれをコンパイルに失敗しました。より正確には†

、疑似デストラクタの呼び出し

+0

面白いことに、これはしかしクランでは動作しないということです。それがバグか、あまりにも悪いルールがあるのか​​どうかは分かりません。 – Brian

+0

実際、最初はgccで試してみました。これは私にとって謎です。 – Flynsee

関連する問題