代码之家  ›  专栏  ›  技术社区  ›  Maarten Bamelis

C++中构造一个“iStimeTabeleStimaby'类型特征

  •  3
  • Maarten Bamelis  · 技术社区  · 6 年前

    是否有可能在C++中构造一个类型特征,以检查给定模板类型是否以给定类型作为模板参数是可实例化的?如果有可能,怎么办?

    例如:

    static_assert(is_template_instantiable_v<std::optional, int, int>);
    static_assert(is_template_instantiable_v<std::vector, double>);
    

    第一个断言将失败,因为 std::optional 只需要一个模板参数。第二个断言没有失败, std::vector 可能仅用单个模板参数实例化,因为其第二个模板参数具有默认值。


    如果以上是可能的,那么在以下情况下,是否可以让类型特征为false(并且不会触发编译错误):

    static_assert(is_template_instantiable_v<std::vector, int &>);
    

    因为 STD::载体 不能用引用作为其值类型来实例化。


    我猜第一个例子可能是可行的复制,而第二个例子不能只用标准的C++代码来完成。

    1 回复  |  直到 6 年前
        1
  •  4
  •   Edgar Rokjān    6 年前

    我假设第一个需求是可行的,方法基于 detection idiom :

    namespace detail
    {
        template<template<typename...> typename T, typename AlwaysVoid, typename... Ts>
        struct is_template_instantiable :
            std::false_type {};
    
        template<template<typename...> typename T, typename... Ts>
        struct is_template_instantiable<T, std::void_t<T<Ts...>>, Ts...> :
            std::true_type {};
    
        template<template<typename...> typename T, typename... Ts>
        inline constexpr auto is_template_instantiable_v =
            is_template_instantiable<T, void, Ts...>::value;
    }
    

    然后,使用:

    template<typename T = void>
    struct X{};
    

    它产生:

    static_assert(detail::is_template_instantiable_v<X>);
    static_assert(detail::is_template_instantiable_v<X, void>);
    static_assert(!detail::is_template_instantiable_v<X, void, int>);
    

    EXAMPLE

    然而,有了这种特质,我无法解决第二个挑战…