2010-02-02 4 views
2

ce code:Pourquoi ce code utilisant `:: boost :: bind` obtient-il une erreur de compilation?

#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; 
} 

est la génération de ces erreurs de compilation:

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> > >)()’ 

Ceci est en g ++ 4.4.1 sur une boîte Fedora 11 avec le paquet de boost-1.37.0 Fedora 11 installé.

Ce code me semble parfaitement kasher. Je ne comprends pas ce qui se passe ici, et le labyrinthe des erreurs liées au développement de modèles est très confus. Est-ce que quelqu'un sait quel est le problème?

Répondre

6
sig.connect(::boost::bind(&Recorder::signalled, &r, _1)); 

Quelle est l'espace réservé _1 pour ici? Il n'est pas nécessaire, connectez-vous à la fonction void -> void. Si vous supprimez l'espace réservé inutile, le code sera compilé.

vous fournir &Recorder::signalled - une fonction de membre de type void Recorder::(void), se lier correctement un pointeur enregistreur, changeant à void -> void, puis en outre laisser un espace réservé _1 - ce qui est évidemment faux.

+0

Je n'ai pas beaucoup utilisé le boost. Tu es manifestement correct et je me sens un peu bête maintenant. :-) Ce que je pensais était que la variable d'espace réservé correspondait en quelque sorte aux variables passées et donc pour chaque variable j'avais besoin d'un espace réservé, ou quelque chose comme ça. J'étais clairement confus. – Omnifarious

+1

@Omnifarious - pas de problème :). Les espaces réservés servent à "ignorer" les paramètres. Par exemple, avec un func 'void Blah :: f (int x, int y, int z)', vous pouvez 'bind (& Blah :: f, & b, & sx, _1, & sz)' et le changer en 'vide (int) 'fonction. –

+0

qui fait beaucoup plus de sens que ce que je pensais. :-) – Omnifarious

Questions connexes