除了概念之外,C++20 中还有其他 void_t 替代品吗?
Beside concepts are there any other void_t replacements in C++20?
假设我不想写一个概念(或者我的编译器不支持它们)并且没有匹配的类型特征是否有 C++20 非 void_t 方法来检查我是否可以构造 A参数 B 和 C?
注意:这是一个 toy example,真正的问题是 void_t 仍然是除了概念之外检查某些东西是否在 C++20 中编译的最佳方法。
template <typename A, typename B, typename C,typename = void>
struct my_is_constructible : std::false_type {};
template <typename A, typename B, typename C>
struct my_is_constructible <A, B,C,
std::void_t<decltype(A(std::declval<B>(), std::declval<C>()))>>
: std::true_type {};
您可以使用检测到的成语,它是对 void_t
的抽象。这几乎是您可以从没有它们的概念中获得的最接近的结果:
template <typename Default, typename AlwaysVoid, template<typename...> typename Op, typename... Args>
struct detector {
using value_t = std::false_type;
using type = Default;
};
template <typename Default, template<typename...> typename Op, typename... Args>
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
using value_t = std::true_type;
using type = Op<Args...>;
};
template <template<typename...> typename Op, typename... Args>
using is_detected = typename detail::detection::detector<nonesuch, void, Op, Args...>::value_t;
template <template<typename...> typename Op, typename... Args>
constexpr auto is_detected_v = detail::detection::detector<nonesuch, void, Op, Args...>::value_t::value;
template <template<typename...> typename Op, typename... Args>
using detected_t = typename detail::detection::detector<nonesuch, void, Op, Args...>::type;
template <typename Default, template<typename...> typename Op, typename... Args>
using detected_or = typename detail::detection::detector<Default, void, Op, Args...>::type;
然后可以这样使用:
template<typename A, typename B, typename C>
using my_is_constructible_expr = decltype(A(std::declval<B>(), std::declval<C>()));
// Trait type that has ::value
template<typename A, typename B, typename C>
using my_is_constructible = is_detected<my_is_constructible_expr, A, B, C>;
// template variable, even closer to concepts
template<typename A, typename B, typename C>
inline constexpr bool my_is_constructible_v = is_detected_v<my_is_constructible_expr, A, B, C>;
假设我不想写一个概念(或者我的编译器不支持它们)并且没有匹配的类型特征是否有 C++20 非 void_t 方法来检查我是否可以构造 A参数 B 和 C?
注意:这是一个 toy example,真正的问题是 void_t 仍然是除了概念之外检查某些东西是否在 C++20 中编译的最佳方法。
template <typename A, typename B, typename C,typename = void>
struct my_is_constructible : std::false_type {};
template <typename A, typename B, typename C>
struct my_is_constructible <A, B,C,
std::void_t<decltype(A(std::declval<B>(), std::declval<C>()))>>
: std::true_type {};
您可以使用检测到的成语,它是对 void_t
的抽象。这几乎是您可以从没有它们的概念中获得的最接近的结果:
template <typename Default, typename AlwaysVoid, template<typename...> typename Op, typename... Args>
struct detector {
using value_t = std::false_type;
using type = Default;
};
template <typename Default, template<typename...> typename Op, typename... Args>
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
using value_t = std::true_type;
using type = Op<Args...>;
};
template <template<typename...> typename Op, typename... Args>
using is_detected = typename detail::detection::detector<nonesuch, void, Op, Args...>::value_t;
template <template<typename...> typename Op, typename... Args>
constexpr auto is_detected_v = detail::detection::detector<nonesuch, void, Op, Args...>::value_t::value;
template <template<typename...> typename Op, typename... Args>
using detected_t = typename detail::detection::detector<nonesuch, void, Op, Args...>::type;
template <typename Default, template<typename...> typename Op, typename... Args>
using detected_or = typename detail::detection::detector<Default, void, Op, Args...>::type;
然后可以这样使用:
template<typename A, typename B, typename C>
using my_is_constructible_expr = decltype(A(std::declval<B>(), std::declval<C>()));
// Trait type that has ::value
template<typename A, typename B, typename C>
using my_is_constructible = is_detected<my_is_constructible_expr, A, B, C>;
// template variable, even closer to concepts
template<typename A, typename B, typename C>
inline constexpr bool my_is_constructible_v = is_detected_v<my_is_constructible_expr, A, B, C>;