如何使用 get std::bind like behavior

How to use get std::bind like behaviour

本文关键字:bind behavior like std 何使用 get      更新时间:2023-10-16

我正在尝试为 std::bind 编写一个包装器。 我的第一个尝试是:

typedef std::function<void(float, int)> tCallback;
template<typename F, class... Args>
tCallback mybind(F f, Args... args)
{
    return std::tr1::bind( f, Args... args, 
        std::tr1::placeholders::_1, std::tr1::placeholders::_2 );
}

给定如下内容:

struct Foo {
   tCallback m__cb;
   setcb(tCallback cb) {m_cb = cb;}
   ....
};
void f1(float f, int i) {}
void f2(int j, float f, int i) {}
Foo foo;
foo.setcb( mybind( f1 ) );   // Fine.
foo.setcb( mybind( f2, 1 ) ); // Not fine.

我做错了什么? 在Visual Studio上,错误指的是以"int &"开头的Args(这让我感到惊讶,但我可能会看到几层错误消息(。 在GCC上,错误是指"参数太多"。 (我不会天真到期望来自像这样的深度模板化代码的有用错误消息!

我是否需要为函数指针和成员函数指针编写 mybind 版本(以及我该如何处理函子(?

注意:我使用的是VS2015和GCC 4.9,因此std::bound和占位符在tr1中。

由于Args... args,您会收到错误,正如评论中已经提到的应该只是args...

还要考虑使用 std::forward 正确转发参数和更喜欢使用 decltype 来确定包装函数的返回类型这不会强制转换为std::function

#include <functional>
typedef std::function<void(float, int)> tCallback;
template<typename F, typename... Args>
auto mybind(F f, Args... args)
    -> decltype(std::bind(std::forward<F>(f), std::forward<Args>(args)...,
        std::placeholders::_1, std::placeholders::_2 ))
//      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
    return std::bind(std::forward<F>(f), std::forward<Args>(args)..., 
//      ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^~~~~
        std::placeholders::_1, std::placeholders::_2 );
}
struct Foo {
   tCallback m_cb;
   void setcb(tCallback cb) {m_cb = cb;}
};
void f1(float f, int i) {}
void f2(int j, float f, int i) {}
int main()
{
    Foo foo;
    foo.setcb( mybind( f1 ) );   // Fine.
    foo.setcb( mybind( f2, 1 ) ); // Not fine.
}

演示


只是关于笔记的快速说明:-(

注意:我使用的是VS2015和GCC 4.9,因此std::bound和占位符在tr1中。

std::bind 已从 Visual Studio 2013(2012( 移动到 std 命名空间中,并且应优先于 tr1 命名空间。

所以实际的问题是

return std::tr1::bind( f, Args... args, 
    std::tr1::placeholders::_1, std::tr1::placeholders::_2 );

实际上是:

return std::tr1::bind( f, args..., 
    std::tr1::placeholders::_1, 
    std::tr1::placeholders::_2, std::tr1::placeholders::_2 );

"Args... args" vs "args..." 是我记错了代码。 双倍的 _2 意味着我试图调用一个参数数量错误的函数。 (我不明白为什么它适用于零绑定参数,但这是一个不同的问题!