我實現了std::experimental::is_detected
基於on this article on cppreference.com(部分代碼在+ working repro之下)。Std :: experimental ::的奇怪MSVC行爲is_detected
它適用於G ++和Clang ++,但會導致MSVC出現奇怪的錯誤行爲:is_detected
似乎總是bool_constant<true>
!
在這裏你可以正確的結果使用gcc 5.x
看到: @ideone.com
但隨着MSVC 19(隨VS2015)測試總是成功:
Z:\>cl /EHsc test.cxx
....
Z:\>test
true, true
所以,這是在一個已知的bug編譯器?它是否與表達式SFINAE沒有正確實現?有什麼解決方法可以用來完成這項工作嗎?
謝謝!
這裏是再現錯誤的代碼的一部分(I省略了接口的其餘部分除了is_detected
提高易讀性):
#include <iostream>
// void_t: void type alias
template<typename...>
using void_t = void;
//
namespace internal
{
// Fallback case
template< typename D,
typename Void,
template<typename...> class Check,
typename... Args
>
struct detect_impl
{
using value_t = std::false_type;
using type = D;
};
// Check succeeded
template< typename D,
template<typename...> class Check,
typename... Args
>
struct detect_impl
< D, void_t< Check<Args...> >, Check, Args... >
{
using value_t = std::true_type;
using type = Check<Args...>;
};
}
// Type representing a missing type.
struct nonesuch
{
nonesuch() = delete;
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
void operator=(nonesuch const&) = delete;
};
template< template<typename...> class Check,
typename... Args
>
using is_detected = typename internal::detect_impl< nonesuch, void, Check, Args... >::value_t;
// Our test
template< typename T >
using is_addable_impl = decltype(std::declval<T>() + std::declval<T>());
template< typename T >
using is_addable = is_detected<is_addable_impl, T>;
auto main(int argc, const char* arv[])
-> int
{
std::cout << std::boolalpha
<< is_addable<int>::value << ", "
<< is_addable<nonesuch>::value << std::endl;
}
編輯:奇怪的是,直接使用void_t成語在MSVC上有效:
#include <iostream>
#include <type_traits>
struct X {};
template< typename T, typename = void >
struct is_addable
: std::false_type
{};
template< typename T >
struct is_addable <T, std::void_t<decltype(std::declval<T>() + std::declval<T>())>>
: std::true_type
{};
int main()
{
std::cout << std::boolalpha
<< is_addable<int>::value << ", "
<< is_addable<X>::value
<< std::endl;
}
輸出:
Z:\>cl /EHsc test.cxx
....
Z:\>test.exe
true, false
如果你正在嘗試VS2015的基礎版本,至少嘗試更新1.已經添加了部分表達式SFINAE支持。 – chris
@chris不幸的是,我已經在使用最新的CTP版本。 – nshct