【问题标题】:Template to Bind non-member static function alongside with member function将非成员静态函数与成员函数绑定的模板
【发布时间】:2020-08-06 06:39:26
【问题描述】:

我有一个类将 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&lt;&amp;Encoder::Encode&gt;) 块将指针传递给 Encoder,以防我们处理成员函数指针。

【问题讨论】:

  • 不能用对象实例调用静态成员函数吗? -- “引用类 T [...] 的静态成员 m:[...] 成员访问表达式 E.m 或 E->m,其中 E 是分别计算为 T 或 T* 的表达式。” - - en.cppreference.com/w/cpp/language/static
  • @user202729 当然可以。但是静态函数的类型与成员函数不同。因此,您不能使用指向对象的指针调用 std::bind

标签: c++ c++11 templates


【解决方案1】:

使用 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)...);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多