Commit d6954b92286f breaks boost::bind usage

Issue #1062 open
Christoph Nelles
created an issue

Hi,

commit d6954b92286f may allow these cool C++11 lambdas, but breaks the really cool boost binds. Compile breaks with ambiguityissues in the templated FunctionCopySlot overloads. Replacing the file FunctorCopySlot.h with the previous version works immediately (as everything is inlined, it is safe).

trivial code example:

bool ClickedQuit1(const CEGUI::EventArgs &args)
{
    return true;
}

void foo()
{
    CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
    CEGUI::Window *sheet = wmgr.createWindow("DefaultWindow", "CEGUIDemo/Sheet");
    CEGUI::Window *quit = wmgr.createWindow("TaharezLook/Button", "CEGUIDemo/QuitButton");
    sheet->addChild(quit);
    quit->subscribeEvent(CEGUI::PushButton::EventClicked, boost::bind(ClickedQuit1, _1));
}

Compile Errors:

c:\mingw\include\cegui-0/CEGUI/FunctorCopySlot.h: In instantiation of 'bool CEGUI::FunctorCopySlot<T>::operator()(const CEGUI::EventArgs&) [with T = boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >]':
tests\ogrebasic\main.cpp:175:1:   required from here
c:\mingw\include\cegui-0/CEGUI/FunctorCopySlot.h:52:41: error: call of overloaded 'call(<unresolved overloaded function type>, const CEGUI::EventArgs&)' is ambiguous
         return call(&T::operator(), args);
                                         ^
c:\mingw\include\cegui-0/CEGUI/FunctorCopySlot.h:52:41: note: candidates are:
c:\mingw\include\cegui-0/CEGUI/FunctorCopySlot.h:73:17: note: bool CEGUI::FunctorCopySlot<T>::call(CEGUI::FunctorCopySlot<T>::Op, const CEGUI::EventArgs&) [with T = boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >; CEGUI::FunctorCopySlot<T>::Op = bool (boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >::*)(const CEGUI::EventArgs&)]
     inline bool call(Op member_fn, const EventArgs& args)
                 ^
c:\mingw\include\cegui-0/CEGUI/FunctorCopySlot.h:78:17: note: bool CEGUI::FunctorCopySlot<T>::call(CEGUI::FunctorCopySlot<T>::OpConst, const CEGUI::EventArgs&) [with T = boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >; CEGUI::FunctorCopySlot<T>::OpConst = bool (boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >::*)(const CEGUI::EventArgs&)const]
     inline bool call(OpConst member_fn, const EventArgs& args)
                 ^
c:\mingw\include\cegui-0/CEGUI/FunctorCopySlot.h:103:17: note: bool CEGUI::FunctorCopySlot<T>::call(CEGUI::FunctorCopySlot<T>::OpNoArgs, const CEGUI::EventArgs&) [with T = boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >; CEGUI::FunctorCopySlot<T>::OpNoArgs = bool (boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >::*)()]
     inline bool call(OpNoArgs member_fn, const EventArgs& /*args*/)
                 ^
c:\mingw\include\cegui-0/CEGUI/FunctorCopySlot.h:108:17: note: bool CEGUI::FunctorCopySlot<T>::call(CEGUI::FunctorCopySlot<T>::OpNoArgsConst, const CEGUI::EventArgs&) [with T = boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >; CEGUI::FunctorCopySlot<T>::OpNoArgsConst = bool (boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >::*)()const]
     inline bool call(OpNoArgsConst member_fn, const EventArgs& /*args*/)
                 ^
c:\mingw\include\cegui-0/CEGUI/FunctorCopySlot.h: In member function 'bool CEGUI::FunctorCopySlot<T>::operator()(const CEGUI::EventArgs&) [with T = boost::_bi::bind_t<bool, bool (*)(OgreSystem&, const CEGUI::EventArgs&), boost::_bi::list2<boost::reference_wrapper<OgreSystem>, boost::arg<1> > >]':
c:\mingw\include\cegui-0/CEGUI/FunctorCopySlot.h:53:5: warning: control reaches end of non-void function [-Wreturn-type]

Tested on Ubuntu 14.04 and MinGW, both with GCC 4.8.x

Comments (14)

  1. Martin Preisler

    Hmm, I am sorry about the breakage. It's me who's responsible.

    Any ideas how to fix this? It's strange that boost::bind functor offers all these overloads. I would expect it to only offer one.

  2. Christoph Nelles reporter

    boost::bind and your FunctorCopySlot are both probably too generic, offering to many possibilities. I am wondering why the compiler considers OpNoArgs/Const to be a viable candidate as it would provide less parameters to the operator() call than required.

    But sorry, i cannot help you with this issue. This boost template black magic is far above my level. Do you really need all these call() variants?

    I found a workaround using a stronger typed temporary variable:

    boost::function<bool (const CEGUI::EventArgs&)>  x =  boost::bind(ClickedQuit1, _1);
    quit->subscribeEvent(CEGUI::PushButton::EventClicked, x);
    
  3. Log in to comment