在这篇文章中(为什么成员函数不能用作模板参数?)我看到可以使用指向成员函数的指针作为模板参数,例如:
struct Foo {
void Bar() { // do something
}
};
template <typename TOwner, void(TOwner::*func)()>
void Call(TOwner *p) {
(p->*func)();
}
int main() {
Foo a;
Call<Foo, &Foo::Bar>(&a);
return 0;
}
但是我想知道如果 Foo::Bar 将 lambda 作为参数,则必须如何调整?那么我必须为“???”添加什么?在以下代码中:
template<typename T>
concept has_call_operator = requires { &T::operator(); };
struct Foo {
void Bar(has_call_operator auto lambda) {}
};
template <typename TOwner, void(TOwner::*func)(???)>
void CallFoo(TOwner *p) {
(p->*func)([](){});
}
这里的问题是
void Bar(has_call_operator auto lambda)
是一个模板。在实例化它之前你不能获取它的地址。您仅在调用时实例化它,因为您希望从形参推导出模板实参。您可以通过将其包装在可用作 auto
模板参数的 lambda 中来推迟实例化:
#include <functional>
template<typename T>
concept has_call_operator = requires { &T::operator(); };
struct Foo {
void Bar(has_call_operator auto lambda) {}
};
template <typename TOwner,auto func>
void CallFoo(TOwner *p) {
std::invoke(func,p,[](){});
}
int main() {
Foo a;
CallFoo<Foo,[](Foo* f,auto g){f->Bar(g); }>(&a);
return 0;
}