MSVC SFINAE:替换不会失败
MSVC SFINAE: Substitution does not fail
我正在尝试制作一种 "has_member"。使用 Clang(对于 msvc)效果很好(我得到 0、1),但使用 MSVC 时效果不佳(我得到 1、1)。
这是我的代码
template<typename T>
using void_t = void;
namespace detail {
template<typename AlwaysVoid, template<typename...> typename Operator, typename ...Args>
struct _is_valid : std::false_type {};
template<template<typename...> typename Operator, typename ...Args>
struct _is_valid<void_t<Operator<Args...>>, Operator, Args...> : std::true_type { using type = Operator<Args...>; };
}
template<template<typename ...> typename Operator, typename ...Args>
using is_valid = detail::_is_valid<void, Operator, Args...>;
template<typename T>
using _has_push_back = decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()));
template<typename T>
using has_push_back = is_valid<_has_push_back, T>;
int main() {
std::cout << has_push_back<float>::value << " " << has_push_back<std::vector<float>>::value << std::endl;
getchar();
return 0;
}
恕我直言,Operator<Args...>
在 detail::_is_valid
中没有失败。但是我不明白如何让它对 MSVC 有效。
我正在使用 Visual Studio 2017
Visual Studio 在 SFINAE 很糟糕。尽管他们声称已经改善了这种情况,但我编写的大部分(如果不是全部)SFINAE 代码(虽然不多)都无法工作甚至无法编译,即使 Clang 和 GCC 处理相同的代码也很好。
将所有失败的代码发送给 Microsoft,这样您就有更大的机会修复它。
你应该试试:
template<typename T> struct make_void {
using type = void;
};
template<typename T>
using void_t = typename make_void<T>::type;
上的信息也可能有所帮助。
我正在尝试制作一种 "has_member"。使用 Clang(对于 msvc)效果很好(我得到 0、1),但使用 MSVC 时效果不佳(我得到 1、1)。
这是我的代码
template<typename T>
using void_t = void;
namespace detail {
template<typename AlwaysVoid, template<typename...> typename Operator, typename ...Args>
struct _is_valid : std::false_type {};
template<template<typename...> typename Operator, typename ...Args>
struct _is_valid<void_t<Operator<Args...>>, Operator, Args...> : std::true_type { using type = Operator<Args...>; };
}
template<template<typename ...> typename Operator, typename ...Args>
using is_valid = detail::_is_valid<void, Operator, Args...>;
template<typename T>
using _has_push_back = decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()));
template<typename T>
using has_push_back = is_valid<_has_push_back, T>;
int main() {
std::cout << has_push_back<float>::value << " " << has_push_back<std::vector<float>>::value << std::endl;
getchar();
return 0;
}
恕我直言,Operator<Args...>
在 detail::_is_valid
中没有失败。但是我不明白如何让它对 MSVC 有效。
我正在使用 Visual Studio 2017
Visual Studio 在 SFINAE 很糟糕。尽管他们声称已经改善了这种情况,但我编写的大部分(如果不是全部)SFINAE 代码(虽然不多)都无法工作甚至无法编译,即使 Clang 和 GCC 处理相同的代码也很好。
将所有失败的代码发送给 Microsoft,这样您就有更大的机会修复它。
你应该试试:
template<typename T> struct make_void {
using type = void;
};
template<typename T>
using void_t = typename make_void<T>::type;