C++11 C++;0x
std::bind需要一个函数包装器,它将在函数包装器之前被调用,并将参数传递给包装的函数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::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
}