2012-09-10 106 views
0

如何創建對模板類中的模板函數的函數回調。以下是我迄今爲止:模板類的模板成員的函數句柄

template <typename SocketType> 
class NettyPBSslSerializer { 
    ... 
    template <typename Handler> 
    void async_read(google::protobuf::Message *pbmess,Handler handler) { 
      void (NettyPBSslSerializer<SocketType>::*f1)(
        const boost::system::error_code&,std::size_t offset,google::protobuf::Message *pbmess,boost::tuple<Handler>) 
        =&NettyPBSslSerializer<SocketType>::async_read_varint <Handler> ; 

      boost::asio::async_read (socket_, 
            boost::asio::buffer(&read_buffer_.at(0), 9), 
            boost::asio::transfer_at_least(1), 
            boost::bind(f1,this,boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, pbmess,boost::make_tuple(handler)) 
            ); 
    } 
    template <typename Handler> 
    void async_read_varint(const boost::system::error_code& e, std::size_t offset,google::protobuf::Message *pbmessp, boost::tuple<Handler> handler) { 
    } 

    .... 
    SocketType socket_; 

} 

我用G ++收到以下錯誤

nettypbserializer.hpp|186| error: expected primary-expression before '>' token 
    nettypbserializer.hpp|186| error: expected primary-expression before ';' token 

線186

=&NettyPBSslSerializer<SocketType>::async_read_varint <Handler> ; 
+0

我把它通過去除模板符編譯所以行186結束了: = NettyPBSslSerializer :: async_read_varint; 我不明白爲什麼這個工程雖然。有誰知道爲什麼? –

回答

1

你不能把一個指向(成員)函數模板,因爲它還不存在。一個解決方案是將Handler類型參數移到NettyPBSslSerializer(以便NettyPBSslSerializer<SocketType, HandlerType>),然後就綁定&NettyPBSslSerializer::async_read_varint ......

編輯:

這其實很簡單。您不能使用指向成員函數模板的指針,但可以構建一個閉包,此函數模板將使用正確的類型實例化並將結果傳遞給boost::async。這裏有一個conceptual implementation

#include <iostream> 

namespace boost { 
    template <typename Stream, typename Handler> 
    void async_read(Stream p_Stream, Handler p_Handler) 
    { 
     p_Handler(); 
    } 
} 

template <typename SocketType> 
class NettyPBSslSerializer { 
    SocketType m_Socket; 

     template <typename Handler> 
     void async_read_varint(Handler handler) { 
       handler(); 
     } 
public: 
     template <typename Handler> 
    void async_read(Handler handler) { 
     boost::async_read(m_Socket, [&]() -> void { 
      this->async_read_varint(handler); 
     }); 
     } 

    NettyPBSslSerializer(SocketType const & p_Socket) : m_Socket(p_Socket) {} 
}; 

void a_handler() 
{ 
    std::cout << "a_handler called" << std::endl; 
} 

int main() 
{ 
    NettyPBSslSerializer<int> tTmp(42); 

     tTmp.async_read(a_handler); 
} 
+0

不,這是不可接受的,我需要在成員函數級別定義的處理程序類型,以便我可以對它使用各種類型的函數。 –

+0

然後還有另一種可能:明確地專門爲您將要使用的'Handler'類型使用這些成員函數。然後,你可以把指針指向這些專門的方法,但是這遠不那麼優雅,並且可能非常笨拙。我真的推薦重新設計,使得'async_read_varint'不需要模板化。 –

+1

我發現它很有趣,所以我發佈了一個解決方案,看看... –