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

问题类似于此处引用的问题
http://www.gotw.ca/gotw/071.htm
但不尽相同:在Sutter的书中,他回答了一个问题,即C类必须提供具有特定签名的成员函数,否则该程序将无法编译。在我的问题中,如果一个类具有该功能,则需要执行某些操作,否则执行“其他操作”。

boost :: serialization面临着类似的问题,但我不喜欢它们采用的解决方案:模板函数默认情况下会调用带有特定签名的自由函数(您必须定义),除非您定义特定的成员函数(在他们的情况下,“序列化”使用两个具有给定类型的参数(带有特定签名),否则将发生编译错误。那就是要实现介入式和非介入式序列化。

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


要成为非侵入式,您必须覆盖boost :: serialization名称空间中的全局“序列化”功能,因此您可以在您的客户端代码中打开名称空间boost和名称空间序列化!
解决该问题的堆栈
混乱是10到12个函数调用。


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

你能给我一个解决这个难题的提示吗?

最佳答案

我不确定我是否理解正确,但是您可能会利用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>());
}

关于c++ - 检查类是否具有给定签名的成员函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46899300/

10-11 22:45
查看更多