使用Boost在C++中从另一个类中调用函数

3

我对c++和boost库都比较新。

我想要做的是从类Baz中调用类Bar的方法foo。以下是基本的需求:

Baz::doSomething() {
    Bar bar;

    boost::thread qux(bar.foo);
}

foo函数可能是这样的:

// bar.cpp

void foo() {
    const int leet = 1337; // Very useful
}

然而,当我尝试编译时,它告诉我:
error: no matching function for call to ‘boost::thread::thread(<unresolved overloaded function type>)’
/usr/local/include/boost/thread/detail/thread.hpp:215:9: note: candidates are: boost::thread::thread(boost::detail::thread_move_t<boost::thread>)
/usr/local/include/boost/thread/detail/thread.hpp:201:18: note:                 boost::thread::thread(F, typename boost::disable_if<boost::is_convertible<T&, boost::detail::thread_move_t<T> >, boost::thread::dummy*>::type) [with F = void (Snake::*)(), typename boost::disable_if<boost::is_convertible<T&, boost::detail::thread_move_t<T> >, boost::thread::dummy*>::type = boost::thread::dummy*]
/usr/local/include/boost/thread/detail/thread.hpp:154:9: note:                 boost::thread::thread()
/usr/local/include/boost/thread/detail/thread.hpp:122:18: note:                 boost::thread::thread(boost::detail::thread_data_ptr)
/usr/local/include/boost/thread/detail/thread.hpp:113:9: note:                 boost::thread::thread(boost::thread&)

这里我漏掉了什么?

3
请注意,当 Baz::doSomething 结束时,无论新线程正在执行什么操作,变量 bar 都将被销毁。这可能会在线程开始之前就发生。 - Eclipse
要么将其作为Baz的成员保留,要么在堆栈上分配它,或者在其他地方创建它。将其保留在堆栈上并将其传递给新线程是有麻烦的,除非你明确等待该线程完成后才从doSomething返回。 - Eclipse
2个回答

3

成员函数和自由函数不同。 你需要使用std::mem_fun_ref来获取一个函数对象,并使用boost::bind(或std::bind如果你的编译器支持)来绑定函数应该在哪个对象上被调用。

最终结果应该像这样:

boost::thread qux(boost::bind(&Foo::bar, bar)); // makes a copy of bar
boost::thread qux(boost::bind(&Foo::bar, &bar)); // make no copy of bar and calls the original instance

或者不使用 bind,让 thread 进行绑定:

boost::thread qux(&Foo::bar, &bar);

我记错了:你不需要使用mem_funboost::bind直接支持成员指针。

感谢解决问题的评论。


2
这里不需要使用 boost::bind -- boost::thread 的构造函数已经在内部进行了绑定。也就是说,boost::thread qux(&Foo::bar, bar); 可以正常工作。 - ildjarn
@ravenspoint:Boost.Bind,以及因此Boost.Thread,可以接受一个指针、引用或智能指针作为其第一个参数的对象。因此,通过值传递bar是完全有效的。 - ildjarn
@ildjarn 但是ravenspoint的观点在某种程度上是正确的,我的代码正在创建一个副本,这显然不是OP的意图。我记得为什么我总是在这种情况下使用std :: mem_fun,我只是觉得bind中的自动化很令人困惑。 - pmr
@pmr:不,你的代码没有制作副本;threadbind 通过引用接受所有参数,而不是值。也就是说,你的代码存在@Eclipse提到的对象生命周期问题,但你没有复制任何对象。 - ildjarn
我指的是第二个参数。正如pmr所指出的,如果您不传递指针,则会得到一个副本。 - ravenspoint
显示剩余4条评论

2
boost::thread qux(boost::bind(
    &Bar::foo,      // the method to invoke
    &bar            // the instance of the class
    ));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接