为什么boost :: bind存储传递的类型的参数而不是函数预期的类型? [英] Why does boost::bind store arguments of the type passed in rather than of the type expected by the function?

查看:151
本文介绍了为什么boost :: bind存储传递的类型的参数而不是函数预期的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在使用提升时遇到了程式码中的错误:: bind

从boost :: bind文档:

From the boost::bind docs:


绑定的参数被复制并由返回的函数对象内部保存。

The arguments that bind takes are copied and held internally by the returned function object.

我假设正在持有的副本是基于函数的签名。但是,它实际上是基于传递的值的类型。

I had assumed that the type of the copy that was being held was based on the signature of the function. However, it is actually based on the type of the value passed in.

在我的情况下,发生隐式转换,将绑定表达式中使用的类型转换为类型由函数接收。我期望这种转​​换发生在绑定的网站,但它发生时,使用的结果函数对象。

In my case an implicit conversion was happening to convert the type used in the bind expression to the type received by the function. I was expecting this conversion to happen at the site of the bind, however it happens when the resulting function object is used.

回想起来,我应该能够使用boost :: bind在类型不兼容时提供错误的事实。仅在调用网站,而不是绑定网站

In retrospect I should have been able to figure this out from the fact that using boost::bind gives errors when types are not compatible only at the call site, not the bind site.

我的问题是:
为什么boost :: bind工作

My question is: Why does boost::bind work this way?


  1. 似乎给出更糟糕的编译器错误消息

  2. 隐式转换发生,并且有多个对函子的调用

但是考虑到Boost的设计,我猜想有一个原因。它是继承自std :: bind1st / bind2nd的行为吗?有什么微妙的原因,为什么这将是难/不可能实现?

But given how well Boost is designed I'm guessing there is a reason. Was it behavior inherited from std::bind1st/bind2nd? Is there a subtle reason why this would be hard/impossible to implement? Something else entirely?

为了测试第二个理论,我写了一些似乎工作的代码片段,但是可能有bind的功能我没有说明因为它只是一个片段:

To test that second theory I wrote up a little code snippet that seems to work, but there may well be features of bind I haven't accounted for since it's just a fragment:

namespace b = boost;
template<class R, class B1, class A1>
   b::_bi::bind_t<R, R (*) (B1), typename b::_bi::list_av_1<B1>::type>
   mybind(R (*f) (B1), A1 a1)
{
   typedef R (*F) (B1);
   typedef typename b::_bi::list_av_1<B1>::type list_type;
   return b::_bi::bind_t<R, F, list_type> (f, list_type(B1(a1)));
}

struct Convertible
{
   Convertible(int a) : b(a) {}
   int b;
};

int foo(Convertible bar)
{
   return 2+bar.b;
}

void mainFunc()
{
   int x = 3;
   b::function<int()> funcObj = mybind(foo, x);
   printf("val: %d\n", funcObj());
}


推荐答案

需要在调用站点处理的参数。

There are different cases where you need the arguments to be processed at the call site.

第一个这样的例子是调用成员函数,你可以在对象的副本上调用成员( boost :: bind (& std :: vector< int> :: push_back,myvector)),这很可能是你不想要的,否则你需要传递一个指针,binder会根据需要解引用指针( boost :: bind(& std :: vector< int> :: push_back,& myvector)) - 注意这两个选项在不同的程序中有意义

The first such example is calling a member function, where you can either have the member called on a copy of the object (boost::bind( &std::vector<int>::push_back, myvector)) which most probably you don't want, or else you need to pass a pointer and the binder will dereference the pointer as needed (boost::bind( &std::vector<int>::push_back, &myvector )) --Note both options can make sense in different programs

另一个重要的用例是将参数通过引用传递给函数。 bind 执行等价于按值传递。库提供了通过辅助函数 ref cref 来包装参数的选项,它们都存储指向实际的对象被传递,并且在调用的地方它们解引用指针(通过隐式转换)。如果转换为目标类型是在绑定时执行的,那么这将是不可能实现的。

Another important use case is passing an argument by reference to a function. bind will copy performing the equivalent to a pass-by-value call. The library offers the option of wrapping arguments through the helper functions ref and cref, both of which store a pointer to the actual object to be passed, and at the place of call they dereference the pointer (through an implicit conversion). If the conversion to the target type was performed at bind time, then this would be impossible to implement.

这篇关于为什么boost :: bind存储传递的类型的参数而不是函数预期的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆