将泛型函数赋给函数指针结构成员



我必须给struct的下列成员赋值:

esp_err_t (*handler)(httpd_req_t *r);

可以看到,它是一个函数指针。我有一个通用模板函数,我想将其分配为handler:

template <class Tmsg>
esp_err_t HandleRpc(httpd_req_t *req){...}

我在泛型模板类中分配handler成员,所以我有一个泛型类型参数Tpayload:

httpd_uri_t cfg = {
...
.handler = HandleRpc<Tpayload>,
...
};

我:

在'>'标记前期望的主表达式

问题在于我不能传递成员方法指针(即esp_err_t (RpcServer::*)(...)),但RpcServer是一个泛型模板类(即有一个泛型参数的模板)。因此,我认为通过在类(全局作用域?)之外创建一个泛型模板函数,并将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)
{

这是一个接受一个形参的函数模板。参数的类型并不重要。关键是每个这个模板的instance将是一个只接受一个形参的函数,总是这样。

在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才标准化,所以其他编译器可能不支持这种语法。

如果您愿意,可以将this声明为指向以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();
}

(注意——你的代码有其他语法错误;如果它们被修正了,一开始,代码似乎是可以编译的;但是如果尝试实例化模板,则会因为类型不匹配而失败)

最新更新