猿问

检查类是否具有给定签名的成员函数。

检查类是否具有给定签名的成员函数。

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

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

Boost:序列化也面临类似的问题,但我不喜欢他们采用的解决方案:默认情况下,模板函数用特定的签名调用一个空闲函数(必须定义),除非您用特定的签名定义了一个特定的成员函数(在他们的情况下,“序列化”使用了给定类型的2个参数),否则会发生编译错误。即实现侵入式序列化和非侵入式序列化。

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

  1. 要成为非侵入性的,您必须重写Boost:序列化命名空间中的全局“序列化”函数,因此您可以在客户端代码中打开命名空间Boost和命名空间序列化!
  2. 解决这个混乱的堆栈是10到12个函数调用。

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

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


慕容森
浏览 441回答 3
3回答

当年话下

我不确定我是否正确地理解了你,但是你可以利用SFINAE在编译时检测函数的存在。代码中的示例(测试类是否具有成员函数size_t USED_Memory()Const)。template<typename&nbsp;T>struct&nbsp;HasUsedMemoryMethod{ &nbsp;&nbsp;&nbsp;&nbsp;template<typename&nbsp;U,&nbsp;size_t&nbsp;(U::*)()&nbsp;const>&nbsp;struct&nbsp;SFINAE&nbsp;{}; &nbsp;&nbsp;&nbsp;&nbsp;template<typename&nbsp;U>&nbsp;static&nbsp;char&nbsp;Test(SFINAE<U,&nbsp;&U::used_memory>*); &nbsp;&nbsp;&nbsp;&nbsp;template<typename&nbsp;U>&nbsp;static&nbsp;int&nbsp;Test(...); &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;const&nbsp;bool&nbsp;Has&nbsp;=&nbsp;sizeof(Test<T>(0))&nbsp;==&nbsp;sizeof(char);};template<typename&nbsp;TMap>void&nbsp;ReportMemUsage(const&nbsp;TMap&&nbsp;m,&nbsp;std::true_type){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;We&nbsp;may&nbsp;call&nbsp;used_memory()&nbsp;on&nbsp;m&nbsp;here.}template<typename&nbsp;TMap>void&nbsp;ReportMemUsage(const&nbsp;TMap&,&nbsp;std::false_type) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{}template<typename&nbsp;TMap>void&nbsp;ReportMemUsage(const&nbsp;TMap&&nbsp;m){ &nbsp;&nbsp;&nbsp;&nbsp;ReportMemUsage(m,&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::integral_constant<bool,&nbsp;HasUsedMemoryMethod<TMap>::Has>());}
随时随地看视频慕课网APP
我要回答