"has_member"のようなものを作ろうとしています。 Clang(msvc用)を使用するとうまくいく(0,1を得る)が、MSVCを使用しても(1、1が得られる)。MSVC SFINAE:置換が失敗しない
はここ
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;
}
IMHO、Operator<Args...>
はdetail::_is_valid
で失敗しない私のコードです。しかし、私はそれをMSVCのために有効にする方法を理解していません。
私はVisual Studioを使用しています。2017
このvoid_tは機能します。しかし、私はなぜこの実装が他のものより優れているのか理解していません(これは私の単純なケースで今まで働いていました)。この新しいvoid_tは、彼が "T"の使用を "保証"しているので、より良いでしょうか? –
':: type'はSFINAEを強制し、標準で' void_t'の単純なエイリアスをサポートする変更/欠陥がありました。 – Jarod42