Как создать функцию обратного вызова для шаблонной функции в шаблонном классе. Вот что у меня так далеко:
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> ;
Вы не можете взять указатель на шаблон функции (члена), так как он еще не существует. Одним из решений было бы переместить Handler
введите параметр в NettyPBSslSerializer
(таким образом NettyPBSslSerializer<SocketType, HandlerType>
) а потом просто привязать &NettyPBSslSerializer::async_read_varint
…
РЕДАКТИРОВАТЬ:
Это на самом деле довольно легко. Вы не можете взять указатель на шаблон функции-члена, но вы можете построить замыкание, где этот шаблон функции будет создан с правильным типом и передаст результат boost::async
, Вот концептуальная реализация:
#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);
}
Других решений пока нет …