c++ 11实现检查是否存在特定的成员函数

  

<强>问题提出

  

最近工作中遇到这样一个需求:实现一个ToString函数将类T型转换到字符串,如果类型T中含有同名方法ToString则直接调用。

  

这样一个ToString实现可以使用<代码> std:: enable_if>   

<>强检查类中是否存在特定成员

  

相同的问题在知乎上有人提出过,@孙明琦的答案提供了一个用于检测特定检测子你在类型T下是否有效的检测器is_detected_v。其中用到了一个c++ 17的<代码> std:: void_t>   

经人提醒,我参考了下标准库在实现交换上做的努力,看到了这样的写法:

        名称空间__swappable_details {   使用std:: swap;      struct __do_is_swappable_impl   {   模板& lt; typename _Tp typename=decltype(交换(std:: declval<_Tp&祝辞(),std:: declval<_Tp&在()))比;   静态true_type __test (int);      模板& lt; typename>   静态false_type __test (…);   };   }      模板& lt; typename _Tp>   struct __is_swappable_impl   :公共__swappable_details:: __do_is_swappable_impl   {   typedef decltype (__test<_Tp>(0))类型;   };      模板& lt; typename _Tp>   struct __is_swappable   :公共__is_swappable_impl<_Tp>::类型   {};      

简单分析可以看到<代码> __is_swappable> 函数接受T作为参数,很有趣的是<代码> __test 函数,如果存在交换函数满足条件,那么<代码>测试(int) 这个重载版本就会被选中。而如果不满足条件,因为推导失败就剩下了测试(…)这个版本。通过这一手段,再设置下返回值分别为真正<代码> 和<代码>假>   

按图索骥,检查是否存在成员ToString的模板就可以这么写:

        名称空间细节   {   struct HasMemberToStringValidator   {   模板& lt; typename T, typename=decltype(及T:: ToString)比;   静态std:: true_type测试(int);      模板& lt; typename>   静态std:: false_type测试(…);   };   }      模板& lt; typename T>   struct HasMemberToString:   公共decltype(细节::HasMemberToStringValidator:: Test (0))   {};      

<代码> HasMemberToString:: value>   

<>强检测是否存在特定成员函数

  

但是上述代码有个问题,如果类T中的ToString是个成员变量,上述检测也会返回真的。

  

解决这一问题的手段是去调用<代码> T:: ToString> T:: ToString>   

这里的另一个问题是,因为ToString是成员函数,那么<代码> decltype (T: ToString()) 这种手段就行不通了,因为成员函数必须带对象进行调用。既然必须要一个对象,那么这里的解决方法就是用上declval来产生一个对象,再用decltype获取返回值类型。

  

按照这个思路,验证过程被改动成:

        struct HasMemberToStringValidator   {   模板& lt; typename T, typename U=typename std:: decay () .ToString())祝辞::类型,   typename=typename std:: enable_if:: type>   静态std:: true_type测试(int);      模板& lt; typename>   静态std:: false_type测试(…);   };      

这个升级版本除了能检查是否存在成员函数ToString以外还对返回值做了限定,确保返回的是字符串。以此类推,还能检查返回是否是u16string, u32string。

  

<强>总结

  

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
  

c++ 11实现检查是否存在特定的成员函数