代码之家  ›  专栏  ›  技术社区  ›  Tomaka17

用SFINAE捕捉函子的结构部分特化

  •  2
  • Tomaka17  · 技术社区  · 16 年前

    出于某种复杂的原因,我想将任何支持的类型T(来自模板)转换为我选择的类型列表。为此,我尝试使用名为“Convert”的模板结构。例如:

    Convert<short>::type should be int
    Convert<int>::type should be int
    Convert<char>::type should be int
    Convert<float>::type should be double
    Convert<double>::type should be double
    Convert<const char*>::type should be std::string
    Convert<std::string>::type should be std::string
    etc.
    

    以上这些都很容易通过模板专业化实现。但有一个案例引发了问题:

    Convert<T>::type where T is a functor should be T
    

    SFINAE 但我没办法让它编译。

    partial specialization cannot match argument list for primary template “(即禁止写“转换”):

    template<typename T, typename = decltype(&T::operator())>
    struct Convert<T>       { typedef T type; };
    

    template parameter not used or deducible in partial specialization

    template<typename T>
    struct Convert<typename std::enable_if<std::is_function<typename T::operator()>::value,T>::type>
     { typedef T type; };
    

    EDIT:我想捕捉使用相同模型的其他泛型,所以我不能只在非专用结构中编写“typedef t type”。

    谢谢

    1 回复  |  直到 16 年前
        1
  •  2
  •   jpalecek    16 年前

    使用一个未使用的模板参数声明主模板:

    template <class T, class = void> Convert;
    

    添加 void 参数设置为您现在使用的模板的所有专门化。

    定义“函子特化”如下:

    template<typename T, typename std::enable_if<std::is_function<typename T::operator()>::value,void>::type>
    

    这意味着你要做第二个论证 无效

    顺便问一下,你为什么用 typename typename T::operator() operator()