代码之家  ›  专栏  ›  技术社区  ›  Joey.Z

如果类型“T”具有要序列化其自身的“template<>struct Writer<T>”,则特征

  •  1
  • Joey.Z  · 技术社区  · 3 年前

    我有一个Writer结构来进行一些序列化

    template<typename T>
    struct Writer {};  // only specialized version has ::wrap_t
    
    template<>
    struct Writer <int> {
        typedef int wrap_t;
    };
    template <typename T>
    using Writer_wrap_t = typename Writer<T>::wrap_t;
    
    template<>
    struct Writer<float> {
        typedef float wrap_t;
    };
    

    我想知道一个类型是否有专门的作家。代码无法按预期工作:

    template<typename T, typename U = Writer_wrap_t <T>>
    struct has_writer : std::true_type {};
    
    template<typename T>
    struct has_writer<T, void> : std::false_type {};
    
    int main() {
        bool b = has_writer <double>::value;
        // error C2794: 'wrap_t': is not a member of any direct or indirect base class of 'Writer<T>'
        // error C2976: 'has_reflect': too few template arguments
        // error C2938: 'Writer_wrap_t ' : Failed to specialize alias template
    }
    

    我想 has_writer<double> 没有使用专业版本 struct has_writer<T, void> : std::false_type {}; ?

    但现在第一个版本的替换失败了,编译器不应该尝试实例化第二个版本吗?

    0 回复  |  直到 3 年前
        1
  •  5
  •   cigien Jorge Eldis    3 年前

    您没有正确使用SFINAE。典型的模式是定义一个主模板,其中第二个模板参数为 void

    template<typename T, typename = void>
    struct has_writer : std::false_type {};
    

    然后使用专门化模板 std::void_t 任何类型的,作为第二个参数检查

    template<typename T>
    struct has_writer<T, std::void_t<Writer_wrap_t <T>>> : std::true_type {};
    

    如果您传递的类型 void_t 形式良好,选择专业化,这是真实的情况,否则选择初级,这是错误的情况。 Writer_wrap_t 只有当传递给它的类型具有成员typedef时,它本身才是格式良好的 wrap_t .