2016-11-14 4 views
2

先日、私はこの問題に遭遇しました。MSVC - void_tでのメンバー検出が正しく動作しません。

#include <iostream> 
#include <type_traits> 
using namespace std; 

template<typename... Ts> struct make_void { typedef void type; }; 
template<typename... Ts> using void_t = typename make_void<Ts...>::type; 

template <class, class = void> 
struct is_func_chrend_ : std::false_type {}; 

template <class T> 
struct is_func_chrend_<T, ::void_t<decltype(std::declval<T>().NextTile())>> : std::true_type {}; 

template <class = void, class = void> 
struct is_addable : std::false_type {}; 

template <class T> 
struct is_addable<T, ::void_t<decltype(std::declval<T>() + std::declval<T>())>> : std::true_type {}; 

int main() { 
    cout << is_addable<int>::value << endl; 
    return 0; 
} 

MSVCでコンパイルすると0、clangまたはgccでコンパイルされている場合は1を表示します。 is_func_chrend_を完全に削除すると、is_addableが正常に動作します。

Makeshift void_tは、C++ 11準拠のコンパイラでのみ使用されます。

+2

あなたのコードは調査されていませんが、VSは完全に式を実装していません。SFINAE – bolov

+0

これを試してみてくださいhttp://stackoverflow.com/q/35669239/3953764 –

+0

これは動作するためにはおそらく最新のMSVCが必要です。私はVS2015 SP3で '1'を取得します。 –

答えて

2

MSVCはまだC++ 11準拠のコンパイラを出荷していません。

彼らの最大の残った問題は、SFINAEの文脈で使用されているdecltypeです。

彼らは状況を定期的に改善し、ますますdecltypeケースが機能するようになりますが、信頼性がありません。

SFINAE式を以前に使用した方法が次回の成功または失敗の方法を変更する可能性があるため、障害が発生したときに偽陽性と偽陰性が発生することがあります。

特定のバージョンのMSVCで処理できるものを慎重に解読し、決してその境界を離れることがない限り、MSVCでdecltypeベースのSFINAEを安全に使用することはできません。私は個人的には、何が効いているのか、頼りにすることができると感じるのには不十分なことを説明しています。

関連する問題