【问题标题】:Why does this code using `::boost::bind` get a compiler error?为什么使用 `::boost::bind` 的代码会出现编译错误?
【发布时间】:2010-02-02 07:28:15
【问题描述】:

这段代码:

#include <boost/signals.hpp>
#include <boost/bind.hpp>
#include <boost/mem_fn.hpp>
#include <iostream>

class Recorder : public ::boost::signals::trackable {
 public:
   void signalled() {
      const void *me = this;
      ::std::cerr << "Recorder at " << me << " signalled!\n";
   }
};

void signalled()
{
   ::std::cerr << "Signalled!\n";
}

int main(int argc, const char *argv[])
{
   ::boost::signal<void ()> sig;
   sig.connect(&signalled);
   {
      Recorder r;
      sig.connect(::boost::bind(&Recorder::signalled, &r, _1));
      sig();
   }
   sig();
   return 0;
}

正在生成这些编译器错误:

In file included from move_constructor.cpp:2:
/usr/include/boost/bind.hpp: In instantiation of ‘boost::_bi::result_traits<boost::_bi::unspecified, void (Recorder::*)()>’:
/usr/include/boost/bind/bind_template.hpp:15:   instantiated from ‘boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >’
move_constructor.cpp:25:   instantiated from here
/usr/include/boost/bind.hpp:67: error: ‘void (Recorder::*)()’ is not a class, struct, or union type
In file included from /usr/include/boost/function/detail/maybe_include.hpp:13,
                 from /usr/include/boost/function/function0.hpp:11,
                 from /usr/include/boost/signals/signal_template.hpp:38,
                 from /usr/include/boost/signals/signal0.hpp:24,
                 from /usr/include/boost/signal.hpp:19,
                 from /usr/include/boost/signals.hpp:9,
                 from move_constructor.cpp:1:
/usr/include/boost/function/function_template.hpp: In static member function ‘static void boost::detail::function::void_function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::function_buffer&) [with FunctionObj = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, R = void]’:
/usr/include/boost/function/function_template.hpp:904:   instantiated from ‘void boost::function0<R>::assign_to(Functor) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, R = void]’
/usr/include/boost/function/function_template.hpp:720:   instantiated from ‘boost::function0<R>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, R = void]’
/usr/include/boost/function/function_template.hpp:1040:   instantiated from ‘boost::function<R()>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, R = void]’
/usr/include/boost/signals/slot.hpp:111:   instantiated from ‘boost::slot<SlotFunction>::slot(const F&) [with F = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, SlotFunction = boost::function<void()>]’
move_constructor.cpp:25:   instantiated from here
/usr/include/boost/function/function_template.hpp:152: error: no match for call to ‘(boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >) ()’

这是在安装了 Fedora 11 boost-1.37.0 软件包的 Fedora 11 机器上使用 g++ 4.4.1。

这段代码在我看来完全符合犹太教规。我不明白这里发生了什么,模板扩展相关错误的迷宫非常混乱。有谁知道问题出在哪里?

【问题讨论】:

    标签: c++ boost compiler-errors


    【解决方案1】:
    sig.connect(::boost::bind(&Recorder::signalled, &r, _1));
    

    这里留下的_1 占位符是什么?不需要,connect 需要 void -&gt; void 函数。如果您删除不必要的占位符,代码将编译。

    你提供&amp;Recorder::signalled——一个void Recorder::(void)类型的成员函数,正确绑定一个Recorder指针,把它改成void -&gt; void,然后另外留下一个占位符_1——有什么明显的问题。

    【讨论】:

    • 我没有使用过很多。你显然是正确的,我现在觉得有点傻。 :-) 我在想的是占位符变量以某种方式与传入的变量匹配,因此对于每个变量我都需要一个占位符或其他东西。我显然很困惑。
    • @Omnifarious - 没问题:)。占位符用于“跳过”参数。例如使用函数void Blah::f(int x, int y, int z),您可以将bind( &amp;Blah::f, &amp;b, &amp;sx, _1, &amp;sz ) 更改为void(int) 函数。
    • 这比我想的更有意义。 :-)
    猜你喜欢
    • 2011-12-27
    • 2014-06-08
    • 1970-01-01
    • 2013-10-08
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2010-10-26
    相关资源
    最近更新 更多