除了概念之外,C ++ 20中是否还有其他void_t替代品?

问题描述

假设我不想编写一个概念(或者我的编译器不支持它们)并且没有匹配的类型特征,是否存在C ++ 20 non void_t方法来检查是否可以使用参数B和C构造A?

注意:这是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 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,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,Args...>::value_t;

template <template<typename...> typename Op,typename... Args>
constexpr auto is_detected_v = detail::detection::detector<nonesuch,Args...>::value_t::value;

template <template<typename...> typename Op,typename... Args>
using detected_t = typename detail::detection::detector<nonesuch,Args...>::type;

template <typename Default,typename... Args>
using detected_or = typename detail::detection::detector<Default,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 C>
using my_is_constructible = is_detected<my_is_constructible_expr,A,B,C>;

// template variable,even closer to concepts
template<typename A,typename C>
inline constexpr bool my_is_constructible_v = is_detected_v<my_is_constructible_expr,C>;

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...