将非成员静态函数与成员函数一起绑定的模板



我有一个类,它将Dispatched命令存储在队列中,并在以后调用它们。命令处理器是一个模板类Encoder,它使用其方法Encoder::Encode来处理命令。但它既可以是成员函数,也可以是静态的非成员函数我该如何绑定它

// specialization that have deduced Encoder's arguments
template <class Encoder, typename ... ArgsT>
class SerialCommunicator<Encoder, std::tuple<ArgsT...>>
{
// ...
Encoder encoder_;
std::queue<std::function<EncodeResult(QByteArray&)> commands_;
mutable std::mutex commandsMutex_;
public:
// ...
void Dispatch(ArgsT ... args)
{
std::lock_guard<std::mutex> lg{commandsMutex_};
commands_.emplace(std::bind(&Encoder::Encode, &encoder_, std::placeholers::_1, 
std::forward<ArgsT>(args)...);
}
// ...
};

使用C++17,如果我们处理成员函数指针,我可以使用if constexpr(std::is_member_function_pointer_v<&Encoder::Encode>)块将指针传递给Encoder

使用SFINAE 不是很优雅的解决方案

template<typename FuncPtr, typename T,
bool = std::is_member_function_pointer<FuncPtr>::value>
struct bind_func
{
template<typename ... Args>
static auto bind(FuncPtr fPtr, T *pObj, Args &&... args)
{
return std::bind(fPtr, std::forward<Args>(args)...);
}
};
template<typename FuncPtr, typename T>
struct bind_func<FuncPtr, T, true>
{
template<typename ... Args>
static auto bind(FuncPtr fPtr, T *pObj, Args &&... args)
{
return std::bind(fPtr, pObj, std::forward<Args>(args)...);
}
};
template<typename FuncPtr, typename T, typename ... Args>
auto bind_func_v(FuncPtr funcPtr, T *pObj, Args &&... args)
{
return bind_func<FuncPtr, T>::bind(funcPtr,
pObj, std::forward<Args>(args)...);
}

最新更新