C++ 11实现检查是否存在特定的成员函数
问题提出 最近工作中遇到这样一个需求:实现一个ToString函数将类型T转换到字符串,如果类型T中含有同名方法ToString则直接调用。 这样一个ToString实现可以使用 检查类中是否存在特定成员 相同的问题在知乎上有人提出过,@孙明琦的答案提供了一个用于检测特定检测子U在类型T下是否有效的检测器is_detected_v。其中用到了一个C++17的 经人提醒,我参考了下标准库在实现swap上做的努力,看到了这样的写法: namespace __swappable_details { using std::swap; struct __do_is_swappable_impl { template <typename _Tp,typename = decltype(swap(std::declval<_Tp&>(),std::declval<_Tp&>()))> static true_type __test(int); template <typename> static false_type __test(...); }; } template <typename _Tp> struct __is_swappable_impl : public __swappable_details::__do_is_swappable_impl { typedef decltype(__test<_Tp>(0)) type; }; template <typename _Tp> struct __is_swappable : public __is_swappable_impl<_Tp>::type {}; 简单分析可以看到 按图索骥,检查是否存在成员ToString的模板就可以这么写: namespace details { struct HasMemberToStringValidator { template <typename T,typename = decltype(&T::ToString)> static std::true_type Test(int); template <typename> static std::false_type Test(...); }; } template <typename T> struct HasMemberToString : public decltype(details::HasMemberToStringValidator::Test<T>(0)) {};
检测是否存在特定成员函数 但是上述代码有个问题,如果类T中的ToString是个成员变量,上述检测也会返回true。 解决这一问题的手段是去调用 这里的另一个问题是,因为ToString是成员函数,那么 按照这个思路,验证过程被改动成: struct HasMemberToStringValidator { template <typename T,typename U = typename std::decay<decltype(std::declval<T>().ToString())>::type,typename = typename std::enable_if<std::is_same<std::string,U>::value>::type> static std::true_type Test(int); template <typename> static std::false_type Test(...); }; 这个升级版本除了能检查是否存在成员函数ToString以外还对返回值做了限定,确保返回的是string。以此类推,还能检查返回是否是u16string、u32string。 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对编程小技巧的支持。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |