返回成员函数指针的C++模板函数编译失败问题求助
C++成员函数指针调用问题解决方法
可正常运行的代码
template<typename... Types> auto countNumberOfTypes() { return sizeof...(Types); } template<typename... Types> consteval auto functionReturnsFunction() { return countNumberOfTypes<Types...>; } functionReturnsFunction<int, const double>()() == 2;
无法编译的代码
struct Test { template<typename... Types> auto countNumberOfTypes() { return sizeof...(Types); } }; template<typename... Types> consteval auto functionReturnsFunction2() { return &Test::countNumberOfTypes<Types...>; } // functionReturnsFunction2<int, const double>()() == 2;
编译报错信息
error: must use ‘.’ or ‘->’ to call pointer-to-member function in ‘&Test::countNumberOfTypes (...)’, e.g. ‘(... ->* &Test::countNumberOfTypes) (...)’
29 | if (functionReturnsFunction2<int, const double>()() == 2)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
解决办法
问题根源:非静态成员函数指针必须依附类的实例才能调用——这类函数隐含this指针参数,需要指向具体的对象实例。以下是三种可行方案:
1. 改为静态成员函数
静态成员函数不依赖类实例,调用逻辑和全局函数完全一致:
struct Test { template<typename... Types> static auto countNumberOfTypes() { return sizeof...(Types); } }; template<typename... Types> consteval auto functionReturnsFunction2() { return &Test::countNumberOfTypes<Types...>; } // 正常调用 functionReturnsFunction2<int, const double>()() == 2;
2. 调用时提供类实例
如果必须保留非静态成员函数,需要创建Test的对象实例,通过.*或->*语法调用:
Test obj; // 使用对象实例调用 (obj.*functionReturnsFunction2<int, const double>())() == 2; // 或者使用指针调用 Test* pObj = &obj; (pObj->*functionReturnsFunction2<int, const double>())() == 2;
3. 用Lambda包装调用逻辑(C++20+)
通过返回无捕获Lambda,在Lambda内部创建临时实例完成调用,对外保持和原全局函数一致的调用方式:
template<typename... Types> consteval auto functionReturnsFunction2() { return []{ return Test{}.countNumberOfTypes<Types...>(); }; } // 直接调用即可 functionReturnsFunction2<int, const double>()() == 2;
内容的提问来源于stack exchange,提问作者XORer
相关产品推荐
相关产品推荐

