如何正确获取Test2模板成员函数operator()的指定模板参数函数指针?
如何获取Test2中operator()的指定函数指针?
已知Test2的所有模板参数,想要获取指向operator()<float, double>的函数指针(其中Args={float},Type2=double),但直接调用会编译报错,以下是具体问题及解决方法:
问题代码示例
template<class Type1> struct Test1 { Type1 value; template<class Type2, class ... Args> bool operator()(const Type2& type) { //... Do something with Args... // return type == value; } }; template<class Type1> struct Test2 { Type1 value; template<class ... Args, class Type2> bool operator()(const Type2& type) { //... Do something with Args... // return type == value; } }; int main() { // 编译正常 auto ptr1 = &Test1<int>::template operator()<float, double>; // 编译报错:编译器将<float, double>推导为Args={float, double},Type2参数缺失 auto ptr2 = &Test2<int>::template operator()<float, double>; }
问题原因
Test2的operator()模板参数顺序是Args...在前、Type2在后。C++中,可变参数模板参数包必须放在模板参数列表的最后位置才能被显式指定或推导。当传入<float, double>时,编译器会把所有参数都匹配到前面的Args...,导致Type2无参数可匹配,进而报错。
解决方法
方法1:调整模板参数顺序(推荐)
将Type2放在Args...前面,和Test1的结构保持一致,即可正常指定参数:
template<class Type1> struct Test2 { Type1 value; // 交换Type2与Args的顺序 template<class Type2, class ... Args> bool operator()(const Type2& type) { //... Do something with Args... // return type == value; } }; // 此时可正常获取函数指针 auto ptr2 = &Test2<int>::template operator()<double, float>;
方法2:使用std::type_identity(C++20及以上)
如果无法修改Test2的结构,可借助C++20引入的std::type_identity强制指定Type2的类型,让编译器明确区分Args和Type2:
#include <type_traits> template<class Type1> struct Test2 { Type1 value; template<class ... Args, class Type2> bool operator()(const Type2& type) { //... Do something with Args... // return type == value; } }; int main() { // 显式指定Type2为double,Args为float auto ptr2 = &Test2<int>::template operator()<float, std::type_identity_t<double>>; }
原理是std::type_identity_t<T>会返回T类型,但编译器不会将其合并到前面的可变参数包中,从而明确Type2的类型。
方法3:手动指定函数指针类型
直接声明函数指针的具体类型,让编译器根据类型匹配对应的operator():
template<class Type1> struct Test2 { Type1 value; template<class ... Args, class Type2> bool operator()(const Type2& type) { //... Do something with Args... // return type == value; } }; int main() { // 声明函数指针类型:参数为const double&,返回bool,属于Test2<int>的成员函数 using FuncPtr = bool (Test2<int>::*)(const double&); // 编译器自动匹配到Args={float}, Type2=double的版本 FuncPtr ptr2 = &Test2<int>::template operator()<float>; }
这里先定义明确的函数指针类型,仅需指定Args的参数,编译器会根据函数指针的参数类型推导出Type2为double。
内容的提问来源于stack exchange,提问作者Caetano
相关产品推荐
相关产品推荐

