2017-05-21 7 views
2

さて、このC++の実装であるis_destructibleは、参照型では機能しません。私はT&T&&のための部分的な特殊化は、任意の参照型を吸い取るだろうと期待していたが、その代わりに、int&は4行目巻き込まれているようですし、コンパイラを作るそれが好む何ですかproducing a hard error.このSFINAEが期待どおりに機能しないのはなぜですか?

namespace detail { 
template<class T, class Enable> struct is_destructible_impl : false_type {}; 
template<class T> struct is_destructible_impl<T&, void> : true_type {}; 
template<class T> struct is_destructible_impl<T&&, void> : true_type {}; 
template<class T> struct is_destructible_impl<T, decltype(declval<T&>().~T())> : true_type {}; 
} 

template<class T> struct is_destructible : 
    detail::is_destructible_impl<remove_all_extents_t<T>, void> {}; 

int main() 
{ 
    static_assert(is_destructible<int&>::value, "oops"); 
} 

<int&, void>に対して<T, (complicated expression that fails)>と一致するのではなく、その誘惑に反して<T&, void>

更新:これはGCCのバグです。 Clangはコードをうまく受け入れます。それで、フォローアップの質問:余分なコーディングをしなくても、このような何かをGCC上で動作させる回避策がありますか?

答えて

4

GCCは間違っています - 不一致擬似デストラクター呼び出しでハードエラーが発生するようです。

template<class T, class U> 
auto f(int) -> decltype(std::declval<T&>().~U()); 

template<class T, class U> 
int f(double); 

using t = decltype(f<int, double>(0)); 

struct C {}; struct D {}; 
using tt = decltype(f<C, D>(0)); 

GCCはtなくttと同様のエラーを発します。

Clangはコードをうまくコンパイルします。


あまり余分なコーディングなしでGCCでこの is_destructible作品のようなものになるだろう回避策はありますか?

だけ参照専門分野を動かす:

namespace detail { 
template<class T, class Enable> struct is_destructible_impl : false_type {}; 
template<class T> struct is_destructible_impl<T, decltype(declval<T&>().~T())> : true_type {}; 
} 

template<class T> struct is_destructible : 
    detail::is_destructible_impl<remove_all_extents_t<T>, void> {}; 
template<class T> struct is_destructible<T&> : true_type {}; 
template<class T> struct is_destructible<T&&> : true_type {}; 
関連する問題