如何解决将通用函数分配给函数指针结构成员
我必须分配结构的以下成员:
esp_err_t (*handler)(httpd_req_t *r);
如你所见,它是一个函数指针。我有一个 generic 模板函数,我想将其分配为 handler
:
template <class Tmsg>
esp_err_t HandleRpc(httpd_req_t *req){...}
我在 generic 模板类中分配了 handler
成员,所以我有一个泛型类型参数 Tpayload
:
httpd_uri_t cfg = {
...
.handler = HandleRpc<Tpayload>,...
};
我明白了:
'>' 标记前的预期主表达式
问题在于我不能传递成员方法指针(IE esp_err_t (RpcServer::*)(...)
),但 RpcServer
是一个 generic 模板类(IE 有一个带有一个泛型参数的模板)。所以我认为通过创建一个 generic 模板函数 outisde 类(全局范围?),并将 RpcServer
实例传递给该函数,我将能够检索我的 RpcServer<T>
实例,一切都会好起来的。
这是我能想出的最少代码来重现问题:
int main()
{
}
template <class T>
class RpcServer{
public:
void RegisterHandler();
};
struct HandlerInfo{
void (*handler)();
};
template <class T>
void Handle(RpcServer<T> test)
{
}
template <class T>
void RpcServer<T>::RegisterHandler(){
HandlerInfo info = {
.handler = Handle<T>;
};
}
我是否错过了显而易见的事情,或者我正在尝试做的事情需要一些更丑陋的技巧?
解决方法
struct HandlerInfo{
void (*handler)();
};
handler
是指向不带参数且不返回任何内容的函数的指针。您可以将此指针设置为指向任何函数。只要它不带参数,不返回任何东西(它的返回类型是void
)。没有例外,这就是 C++ 的工作方式,它是一种强类型语言。
template <class T>
void Handle(RpcServer<T> test)
{
这是一个接受一个参数的函数的模板。参数的类型并不重要。关键是这个模板的每个实例都是一个函数,它总是只接受一个参数。
在 C++ 中,指向没有参数的函数的指针只能设置为指向这样的函数。您不能将此函数指针设置为指向带有一个参数、两个参数或十个参数的函数。它只能设置为一个参数正好为零的函数。那是因为那是指针指向的东西。
如果您要更改模板函数使其不带参数,那么当然可以:
int main()
{
}
template <class T>
class RpcServer{
public:
void RegisterHandler();
};
struct HandlerInfo{
void (*handler)();
};
template <class T>
void Handle()
{
}
template <class T>
void RpcServer<T>::RegisterHandler(){
HandlerInfo info = {
.handler = Handle<T>
};
}
这是在 gcc 10 上编译的。“.member”初始化语法已经被 gcc 支持很长时间了,但它只是从 C++20 开始标准化,所以其他编译器可能不支持这种语法。
如果您愿意,您可以将其声明为指向以 RpcServer<int>
作为其参数的函数的指针:
struct HandlerInfo{
void (*handler)(RpcServer<int>);
};
现在,您将能够初始化它以指向这样的函数:
HandlerInfo info = {
.handler = Handle<int>
};
HandleInt
实例化一个接受此类参数的函数,因此类型完全匹配。
或者,使 HandlerInfo
本身成为匹配模板:
template <class T>
class RpcServer{
public:
void RegisterHandler();
};
template<class T>
struct HandlerInfo{
void (*handler)(RpcServer<T>);
};
template <class T>
void Handle(RpcServer<T> )
{
}
template <class T>
void RpcServer<T>::RegisterHandler(){
HandlerInfo<T> info = {
.handler = Handle<T>
};
}
int main()
{
RpcServer<int> server;
server.RegisterHandler();
}
(注意——你的代码有其他语法错误;如果它们被修复,一开始看起来代码会编译;但是如果尝试实例化模板,它会因为类型不匹配而失败)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。