C++中将模板函数作为函数参数传入的编译问题求助
编译错误根因
- 成员函数模板无法直接作为参数传递:
Getter1、Getter2是结构体B的成员模板,你无法直接将模板名称作为普通函数参数传递,模板本身不是可执行实体,且成员函数调用需要绑定对应实例。 - 模板调用语法缺失:在
FooCore中调用入参f的模板方法时,没有加template关键字,编译器会将<解析为小于运算符,直接触发语法错误。
修复方案
采用泛型Lambda包装成员模板调用,补齐模板调用语法即可,以下是完整可编译代码:
#include <string> #include <vector> class A { public: template <typename T> T Getter1() { return T(); } template <typename T> T Getter2() { return T(); } }; // C++14及以下可以自行实现type_identity,C++20可直接用std::type_identity template<typename T> struct type_identity { using type = T; }; struct B { template <typename T> T Getter1() { return _a.Getter1<T>(); } template <typename T> T Getter2() { return _a.Getter2<T>(); } B(const A& a, bool scalar, int i) : _a(a), _scalar(scalar), _i(i) {} template <typename Func> std::string FooCore(Func f) { if (_scalar) // 传递类型标识给lambda,获取对应返回值 return f(type_identity<std::string>{}); else { auto temp = f(type_identity<std::vector<std::string>>{}); if (temp.size() > 0) return temp[0]; else return "dummy"; } } std::string Foo() { if (_i == 1) // 用lambda包装Getter1调用,捕获当前实例 return FooCore([this](auto t) { return this->Getter1<typename decltype(t)::type>(); }); else return FooCore([this](auto t) { return this->Getter2<typename decltype(t)::type>(); }); } A _a; bool _scalar; int _i; }; int main() { A a; B b(a, true, 1); b.Foo(); }
如果使用C++20及以上版本,可以用更简洁的泛型lambda显式模板参数写法:
template <typename Func> std::string FooCore(Func f) { if (_scalar) return f.template operator()<std::string>(); else { auto temp = f.template operator()<std::vector<std::string>>(); return temp.empty() ? "dummy" : temp[0]; } } std::string Foo() { if (_i == 1) return FooCore([this]<typename T>() { return this->Getter1<T>(); }); else return FooCore([this]<typename T>() { return this->Getter2<T>(); }); }
内容的提问来源于stack exchange,提问作者user4148224
相关产品推荐
相关产品推荐

