C++中如何检测函数参数列表以实现泛型函数的入参自动匹配调用
实现方案
你可以通过C++17的if constexpr结合std::is_invocable_v 实现该判断逻辑,这是最简洁的实现方式,所有判断在编译期完成,没有运行时额外开销。
完整可运行代码
#include <stdio.h> #include <vector> #include <type_traits> using namespace std; template <class USERDEF> void builtin(USERDEF userdef){ std::vector<int> vec = {1, 2, 3}; // 编译期判断是否可以传入vector<int>&调用 if constexpr (std::is_invocable_v<USERDEF, vector<int>&>) { userdef(vec); } // 编译期判断是否可以传入两个迭代器调用 else if constexpr (std::is_invocable_v<USERDEF, vector<int>::iterator, vector<int>::iterator>) { userdef(vec.begin(), vec.end()); } // 参数都不匹配的分支 else { exit(-1); } } void userdef1(vector<int> &vec){ for(auto it=vec.begin(); it!=vec.end(); it++) printf("%d ", *it); printf("\n"); } void userdef2(vector<int>::iterator begin, vector<int>::iterator end){ for(auto it=begin; it!=end; it++) printf("%d ", *it); printf("\n"); } int main(){ builtin(userdef1); builtin(userdef2); }
兼容C++11/14的实现方案
如果你的编译环境不支持C++17,可以通过SFINAE规则写重载辅助函数实现同样效果:
// 匹配可接收vector<int>&参数的重载 template <class USERDEF> auto builtin_impl(USERDEF userdef, vector<int>& vec, int) -> decltype(userdef(vec), void()) { userdef(vec); } // 匹配可接收两个迭代器参数的重载 template <class USERDEF> auto builtin_impl(USERDEF userdef, vector<int>& vec, long) -> decltype(userdef(vec.begin(), vec.end()), void()) { userdef(vec.begin(), vec.end()); } template <class USERDEF> void builtin(USERDEF userdef){ std::vector<int> vec = {1, 2, 3}; builtin_impl(userdef, vec, 0); }
内容的提问来源于stack exchange,提问作者LI.LE
相关产品推荐
相关产品推荐

