我最近在使用boost::bind时遇到了代码中的错误。
来自 boost::bind 文档:
bind 接受的参数由返回的函数对象在内部复制和保存。
我假设所持有的副本的类型基于函数的签名。但是,它实际上是基于传入的值的类型。
在我的例子中,发生了隐式转换,将绑定表达式中使用的类型转换为函数接收到的类型。我期待这种转换发生在绑定的位置,但是当使用生成的函数对象时会发生这种情况。
回想起来,我应该能够从以下事实中弄清楚这一点:当类型仅在调用站点而不是绑定站点不兼容时,使用 boost::bind 会产生错误。
我的问题是:为什么 boost::bind 会这样工作?
- 它似乎给出了更糟糕的编译器错误消息
- 当发生隐式转换并且对函子有多次调用时,它似乎效率较低
但是考虑到 Boost 的设计有多好,我猜这是有原因的。它是从 std::bind1st/bind2nd 继承的行为吗?是否有一个微妙的原因为什么这很难/不可能实现?完全不同的东西?
为了测试第二个理论,我编写了一个似乎可行的小代码片段,但很可能有一些我没有考虑到的绑定功能,因为它只是一个片段:
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());
}