2016-11-14 36 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; 
} 

顯示0,如果在鐺或GCC編譯MSVC,1編譯時。 完全刪除is_func_chrend_使得is_addable再次正常工作。

權宜之計void_t僅用於C++ 11兼容的編譯器。

+2

沒有調查你的代碼,但VS沒有完全實現表達式SFINAE – bolov

+0

試試這個http://stackoverflow.com/q/35669239/3953764 –

+0

你可能需要絕對最新的MSVC才能工作。我用VS2015 SP3獲得'1'。 –

回答

2

MSVC還沒有推出一款C++ 11兼容的編譯器。

他們最大的剩下的問題是decltype在SFINAE上下文中使用。

他們定期改善這種狀況,使得越來越多的decltype箱子工作,但它是不可靠的。

當事情出錯時,它被破壞的方式通常會產生誤報和誤報,並且故障是非本地的,因爲您以前使用SFINAE表達式可能會改變下次如何成功或失敗。

你根本不能安全地使用decltype基於SFINAE在MSVC,除非你仔細解碼你的MSVC的特定版本可以處理,並且永遠不會離開這些邊界。我個人發現他們對什麼有效的描述,以及哪些內容沒有足夠清晰地認爲我可以可靠地使用它。