【问题标题】:Why can't I use a boost::function in an Objective-C++ block?为什么我不能在 Objective-C++ 块中使用 boost::function?
【发布时间】:2011-03-25 22:04:25
【问题描述】:

以下代码抛出异常

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();
}();

但是,根据the documentation on blocks

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

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

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

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

为什么带有boost::function 的版本不起作用?

【问题讨论】:

  • 我不是 boost 专家,但我冒险猜测它与 boost::function&lt;&gt; 类型的 const 复制构造函数 相关(根据引用的文档)。
  • 在没有绑定调用的情况下是否会出现同样的错误(免费功能不需要,请参阅here)?使用可移植语法 function0 而不是 function 怎么样?
  • 我也对bind() 调用感到好奇,这是不必要的,可能是导致错误的原因。
  • @academicRobot,@lefticus - 没有bind()调用没有区别(而且我的实际情况需要绑定一些参数)

标签: c++ objective-c block objective-c++ boost-function


【解决方案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 复制构造函数”,我不确定会调用什么。

【讨论】:

    【解决方案2】:

    你答案中的例子,

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-25
      • 2012-05-04
      • 2017-12-15
      • 2014-12-20
      • 2015-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多