将模板化函数作为参数传递给另一个函数
问题
我正在尝试创建一个在参数包中搜索类型的函数,然后创建一个 lambda 来调用另一个具有该类型的函数作为模板参数,例如:
auto fn = findType<MyType, SomeType, OtherType>("OtherType");
fn(otherFn) == otherFn<OtherType>();
我想写这样的东西:
template<class T, class ...Ts>
auto findType(const std::string& name) {
if (refl::is_reflectable<T>() && refl::reflect<T>().name == name) {
return []<class Fn>(Fn fn) {
fn<T>();
};
}
return findType<Ts...>(name);
}
但是,C++ 似乎没有意识到fn可以使用模板类型进行参数化。
我使用的是 gcc10 和 C++20,所以如果可能的话,我也可以使用概念。
我相信问题可以概括为:如何将模板参数化函数传递给另一个函数?
template<class C>
void fn() {}
template<class Fn, class Arg>
void mainFn(Fn fn) {
fn<Arg>(); // ???
}
尝试搜索
我看过模板模板参数,但这似乎只适用于模板类型,而不是函数调用。
我也看过 C++ 概念,但std::invokable不接受模板参数和要求似乎也不允许这样的表达式:
return []<class Fn>(Fn fn) requires requires { fn<T>(); } {
回答
函数参数是变量。不是可变模板;只是常规的旧变量。并且不能为非模板变量提供模板参数。
您不能在任何地方传递函数模板。您只能传递函数模板的特定实例。最接近你想要的是传递一个具有模板化operator()重载的类型,但除非你可以通过推导提供模板参数,否则调用它的唯一方法是通过fn.operator()<TemplateArguments>(params)。所以你不妨给它一个有意义的名字。