我想创建一个包装器来简化处理程序绑定(bind)的编写,这样我只需要提供回调和数据指针即可。
这是我的代码:
#include <utility>
template <typename Func, typename Data>
class Handler
{
const Func & m_func;
volatile Data & m_data;
public:
Handler(const Func & f, Data & d) :
m_func(f),
m_data(d)
{}
Handler(const Handler & cpy) :
m_func(cpy.m_func),
m_data(cpy.m_data)
{}
template<typename Res=void, typename... Args>
Res operator()(Args... args) const
{
return m_func(m_data, std::forward<Args>(args)... );
}
};
/* I need help to handle this specialization */
template<typename T>
template<typename Res=void, typename... Args>
Res Handler<(T::*)(Args...), T*>::operator()(Args... args) const
{
return (m_data->*m_func)(std::forward<Args>(args)... );
}
template <typename Func, typename Data>
inline Handler<Func, Data> handler(Func f, Data d)
{
return Handler<Func, Data>(f, d);
}
目标是像这样使用它:
boost::asio::async_read(socket,
boost::asio::buffer(d, n),
handler(callback, session)
);
或者像这样:
boost::asio::async_read(socket,
boost::asio::buffer(d, n),
handler(&Object::method, this_ptr)
);
但我在处理后一种情况的特化时遇到问题...
最佳答案
如果您真的想编写自己的模板,那么您的模板中有很多需要修复的地方。首先,您要保留对临时对象的引用。您的 handler()
函数需要自己获取引用,或者您需要保留值。更愿意保持值(value)观。如果用户想要传递引用,他们总是可以使用 std::ref
。让我们从那开始吧。这是一个带有数据的简单处理程序:
template <typename Func, typename Data>
struct Handler
{
Func func; // NB: not a reference
Data data;
template<class... Args>
auto operator()(Args&&... args) const // NB: this wasn't a forwarding ref before
-> decltype(func(data, std::forward<Args>(args)...))
{
return func(data, std::forward<Args>(args)... );
}
};
好吧,现在我们有了一个聚合,它已经是可复制和可移动的,我们想要的所有好东西都不必自己写出来(不是说你的 Handler
是可移动的 - 但移动它调用复制构造函数...)
现在,我们可以写出我们的函数了:
template <class F, class D>
Handler<std::decay_t<F>, std::decay_t<D>> handler(F&& f, D&& d) {
return {std::forward<F>(f), std::forward<D>(d)};
}
要处理成员函数,您只需要单独重载handler
。其他一切都保持不变,我们只是有条件地用 mem_fn
包装指向成员的指针:
template <class R, class T>
auto handler(R T::* p, T* cls)
-> Handler<decltype(std::mem_fn(p)), T*>
{
return {std::mem_fn(p), cls};
}
嗯瞧。
关于c++ - 处理指向模板中成员的指针,同时创建更简单的 `bind` 以与 asio 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39372213/