簡體   English   中英

將通用 function 分配給 function 指針結構成員

[英]Assign generic function to function pointer struct memeber

我必須分配結構的以下成員:

esp_err_t (*handler)(httpd_req_t *r);

如您所見,它是一個 function 指針。 我有一個通用模板 function 我想指定為handler

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

我在通用模板 class 中分配handler成員,所以我有一個通用類型參數Tpayload

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

我得到:

'>' 標記之前的預期主表達式

問題在於我無法傳遞成員方法指針(IE esp_err_t (RpcServer::*)(...) ),但RpcServer通用模板 class (IE 有一個帶有一個通用參數的模板)。 So I thought that by creating a generic template function outisde the class (global scope?), and passing the RpcServer instance into that function, I would be able to retrieve my instance of RpcServer<T> and all would be well.

這是我能想出的重現該問題的最少代碼量:

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是一個指向 function 的指針,它不帶參數,也不返回任何東西。 您可以將此指針設置為指向任何 function。 只要它不帶參數,並且不返回任何東西(它的返回類型是void )。 這一點也不例外,這就是 C++ 的工作原理,它是一種強類型語言。

template <class T>
void Handle(RpcServer<T> test)
{

這是采用一個參數的 function 的模板。 參數的類型不重要。 關鍵是這個模板的每個實例都是一個 function,它總是只接受一個參數。

在C++中,指向沒有參數的function的指針只能設置為指向這樣的function。 您不能將此 function 指針設置為指向一個 function 接受一個參數、兩個參數或十個參數。 它只能設置為采用零參數的 function。 那是因為那是指針所指向的。

如果您要更改模板 function 使其不帶參數,那么這當然可以:

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>作為參數的 function 的指針:

struct HandlerInfo{
    void (*handler)(RpcServer<int>);
};

現在,您將能夠將其初始化為指向這樣的 function:

HandlerInfo info = {
    .handler = Handle<int>
};

HandleInt實例化了一個采用此類參數的 function,因此類型完全匹配。

或者,或者,使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();
}

(注意——你的代碼有其他語法錯誤;如果它們被修復,看起來,一開始,代碼會編譯;但如果嘗試實例化模板,它會由於類型不匹配而失敗)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM