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

确定类是否具有函数[duplicate]

  •  2
  • tstenner  · 技术社区  · 15 年前

    我要求一个模板技巧来检测一个类是否具有给定签名的特定成员函数。

    这个问题与这里引用的问题相似 http://www.gotw.ca/gotw/071.htm 但不一样:在萨特的书中,他回答了一个问题:C类必须提供一个具有特定签名的成员函数,否则程序将无法编译。在我的问题中,如果一个类有这个函数,我需要做一些事情,否则就做“其他事情”。

    一个类似的问题被Booo::序列化,但我不喜欢他们采用的解决方案:一个模板函数,默认情况下调用一个具有特定签名的自由函数(除非你定义了一个特定的成员函数)(在其情况下,“序列化”)需要2个函数。给定类型的参数)具有特定签名,否则将发生编译错误。即实现侵入式和非侵入式序列化。

    我不喜欢这个解决方案有两个原因:

    1. 要实现非侵入性,您必须重写boost::serialization namespace中的全局“serialize”函数,以便在客户端代码中打开namespace boost和namespace serialization!
    2. 解决这个问题的方法 混乱是10到12个函数调用。

    我需要为没有该成员函数的类定义一个自定义行为,并且我的实体在不同的命名空间中(并且我不想在另一个命名空间中重写在一个命名空间中定义的全局函数)

    你能给我一个暗示来解决这个难题吗?

    0 回复  |  直到 6 年前
        1
  •  0
  •   prehistoricpenguin    6 年前

    我不确定我是否正确理解您,但是您可以利用sfinae在编译时检测函数的存在。我的代码中的示例(测试类是否具有成员函数size_t used_memory()const)。

    template<typename T>
    struct HasUsedMemoryMethod
    {
        template<typename U, size_t (U::*)() const> struct SFINAE {};
        template<typename U> static char Test(SFINAE<U, &U::used_memory>*);
        template<typename U> static int Test(...);
        static const bool Has = sizeof(Test<T>(0)) == sizeof(char);
    };
    
    template<typename TMap>
    void ReportMemUsage(const TMap& m, std::true_type)
    {
            // We may call used_memory() on m here.
    }
    template<typename TMap>
    void ReportMemUsage(const TMap&, std::false_type)
    {
    }
    template<typename TMap>
    void ReportMemUsage(const TMap& m)
    {
        ReportMemUsage(m, 
            std::integral_constant<bool, HasUsedMemoryMethod<TMap>::Has>());
    }