C++11 C++;0x

C++11 C++;0x,c++11,bind,decorator,boost-asio,C++11,Bind,Decorator,Boost Asio,std::bind需要一个函数包装器,它将在函数包装器之前被调用,并将参数传递给包装的函数 std::function<void (int)> foo = postbind<int>(service, handle); std::function foo=postbind(服务、句柄); 这也是我能做到的。我想让postbind对象自动推断类型。我曾尝试创建一个对象生成器make_postbind(服务、句柄),但它无法自动推断类型 下面我写了一个测试用例。使用:g+

std::bind需要一个函数包装器,它将在函数包装器之前被调用,并将参数传递给包装的函数

std::function<void (int)> foo = postbind<int>(service, handle);
std::function foo=postbind(服务、句柄);
这也是我能做到的。我想让postbind对象自动推断类型。我曾尝试创建一个对象生成器make_postbind(服务、句柄),但它无法自动推断类型

下面我写了一个测试用例。使用:g++-o postbind postbind.cpp-std=c++0x-lboost\u系统编译

我想接电话:

std::function<void (int)> func = postbind<int>(strand, std::bind(foo, myfoo(), 'a', _1));
std::function func=postbind(串,std::bind(foo,myfoo(),'a',_1));
具体到:

std::function<void (int)> func = postbind(strand, std::bind(foo, myfoo(), 'a', _1));
std::function func=postbind(串,std::bind(foo,myfoo(),'a',_1));
但是我不知道怎么做。在我的代码中,我开始得到一些非常冗长的后绑定模板专门化,它们开始:)

#包括
#包括
#包括
#包括
#包括
使用名称空间boost::asio;
使用std::shared_ptr;
typedef共享服务;
类型定义共享工作;
typedef共享\u ptr串\u ptr;
typedef std::共享工作;
使用std::占位符::1;
模板
类后绑定
{
公众:
typedef std::函数;
后绑定(strand_ptr strand,函数memfunc)
:strand_uu(strand),memfunc_u(memfunc)
{
}
void运算符()(参数…参数)
{
链->post(std::bind(memfunc),std::forward(params)…);
}
私人:
钢绞线ptr钢绞线;
函数memfunc;
};
// --------------------------------------------
结构myfoo
{
字符a;
int b;
};
无效运行(服务\u ptr服务)
{
服务->运行();
}
void foo(myfoo foo,char a,int x)
{

std::cout您可以将模板专门化移动到另一个类中,这样您就不必将它们放在对
postbind
的调用中。例如,创建一个空类,其目的是简单地保存所有冗长的模板参数:

template<typename... Args>
struct post_bind_traits {};
现在,您可以调用
postbind
,前提是您可以访问头文件中的
typedef
定义,如下所示:

typedef post_bind_traits<int, int> pb_int_int;
typedef post_bind_traits<double, int> pb_double_int;
//... additional definitions
template<typename... Args>
class postbind<post_bind_traits<Args...>> //add this partial specialization
{
public:
    typedef std::function<void (Args...)> function;

    postbind(strand_ptr strand, function memfunc)
      : strand_(strand), memfunc_(memfunc)
    {
    }

    void operator()(Args... params)
    {
        strand_->post(std::bind(memfunc_, std::forward<Args...>(params)));
    }
private:
    strand_ptr strand_;
    function memfunc_;
};
postbind<pb_int_int>::function func = postbind<pb_int_int>(/* arguments */);
postbind::function func=postbind(/*参数*/);

将所有复杂的
typedef
打包到头文件中,您的主代码模块文件中的代码集就会更干净。

我认为答案是不可能的。这是因为std::function和std::bind的返回值之间存在差异

  • 声明时必须指定std::function的函数签名
  • std::bind返回的functor的签名实际上有一个可变的模板参数,在调用其运算符()之前无法确定。这意味着签名在声明时不是唯一的,而声明时肯定是在计算时间之前
看看预期的调用,
std::function func=postbind(strand,std::bind(foo,myfoo(),'a',_1);
。实际上,编译器只知道绑定的参数和一些占位符。过了一段时间,它的运算符()就可以了调用,则未绑定的参数将替换占位符,现在编译器可以检查所有参数是否与函数签名匹配

如果以上句子太难理解,请让我展示一些代码:

void foo(int) {}

foo(1);          // Correct.
foo(1, 2);       // Illegal, signature mismatched.

auto f = std::bind(foo, _1);  // Here f has no idea about unbound args for foo.

f(1);         // OK, 1 matches int.
f(1, 2);      // OK too, although 2 is used.
f(1, 1, 1);   // Same as before ones.

auto func = postbind(
    strand, std::bind(foo, _1));    // If this is acceptable,

func(99);       // this is a correct invocation then.
func(99, 98);   // And this should also be happy for compiler. Ambiguity!
因此,您必须在绑定时显式指定签名

但无论如何,这里有一个代码片段,我想它可能是一个替代解决方案:

template <typename... ArgTypes>
void do_post(strand_ptr strand, ArgTypes&&... args)
{
    strand->post(std::bind(std::forward<ArgTypes>(args)...));
}

int main()
{
    // some code

    auto original_closure = std::bind(foo, myfoo(), 'a', _1);
    auto final_closure = std::bind(
        do_post<decltype(std::ref(original_closure)), int>,  // signature deduced here
        strand, std::ref(original_closure), _1);  // std::ref used for inner std::bind
    final_closure(99);

    // others
}
模板
void do_post(股线股线股线、ArgTypes&…args)
{
串->post(std::bind(std::forward(args)…);
}
int main()
{
//一些代码
自动原始_closure=std::bind(foo,myfoo(),'a',_1);
自动最终关闭=标准::绑定(
请勿张贴,//此处签名
串,std::ref(原始的_闭包),_1);//std::ref用于内部std::bind
最终关闭(99);
//其他
}
template <typename... ArgTypes>
void do_post(strand_ptr strand, ArgTypes&&... args)
{
    strand->post(std::bind(std::forward<ArgTypes>(args)...));
}

int main()
{
    // some code

    auto original_closure = std::bind(foo, myfoo(), 'a', _1);
    auto final_closure = std::bind(
        do_post<decltype(std::ref(original_closure)), int>,  // signature deduced here
        strand, std::ref(original_closure), _1);  // std::ref used for inner std::bind
    final_closure(99);

    // others
}