3

以下代码抛出异常

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_function_call> >'
  what():  call to empty boost::function

在行f()(在执行块时):

void foo(); // assume this is defined somewhere
boost::function<void()> f = boost::bind(&foo);

^(void) {
   f();
}();

但是,根据有关 blocks 的文档

通常,您可以在块中使用 C++ 对象。在成员函数中,对成员变量和函数的引用是通过隐式导入的 this 指针进行的,因此看起来是可变的。如果复制块,有两个注意事项:

  • 如果您有一个 __block 存储类来存储基于堆栈的 C++ 对象,则使用通常的复制构造函数。

  • 如果您在块中使用任何其他基于 C++ 堆栈的对象,则它必须具有 const 复制构造函数。然后使用该构造函数复制 C++ 对象。

通常这似乎是正确的;如果我将f上面替换为带有 的简单类的实例operator()(),则上面的代码将按预期运行。

为什么版本不boost::function工作?

4

2 回答 2

1

看来,如果我用 修改声明__block,它可以正常工作:

__block boost::function<void()> f = boost::bind(&foo);

我仍然不确定为什么会这样 - 正如@Richard 在上面的评论中提到的那样,它必须与“const 复制构造函数”而不是“通常的复制构造函数”有关。不过,我不知道如何检查这种差异;以下工作正常:

const boost::function<void()> f = boost::bind(&foo);
const boost::function<void()> g(f);
g();

如果这不调用“const 复制构造函数”,我不确定会发生什么。

于 2011-04-06T05:05:00.117 回答
0

你回答中的例子,

const boost::function<void()> f = boost::bind(&foo);
const boost::function<void()> g(f);
g();

有效,因为您在operator()创建其被调用者的同一范围内调用。f()也可以在块范围之外工作,并且调用foo()将在块范围内工作,因为它是一个经典函数,并且在调用时不被视为“修改”。将对象从包含范围传递到块范围时,会进行对const 复制构造函数的引用调用。似乎const 复制构造函数中存在的任何差异都无法将对象的一部分复制到块范围。

于 2011-04-09T13:41:37.023 回答