C++ “no match for call” error in sigc::mem_fun

975 views Asked by At

I use sigc::mem_fun to connect a handler function, which is a class member, to a GTKMM event. I call sigc::mem_fun from the same class the handler function is declared in.

// Interface.h

class Interface {
public:
    Interface(...);
// ...
private:
    Gtk::ComboBoxText *optionChoiceComboBoxText = nullptr; //Initialized in constructor
    Gtk::Switch optionControlSwitch;

    void optionChangedHandler();

    void switchHandler();
// ...
};

// Interface.cpp

Interface::Interface(...) {
    // ...
    optionChoiceComboBoxText->signal_changed().connect(sigc::mem_fun(*this, &Interface::optionChangedHandler));
    optionControlSwitch.signal_state_changed().connect(sigc::mem_fun(*this, &Interface::switchHandler)); // Error is here
}


void Interface::optionChangedHandler() {
    // Do something
}

void Interface::switchHandler() {
    // Do something
}

This is the error:

In file included from /usr/include/sigc++-2.0/sigc++/functors/slot.h:7:0,
                 from /usr/include/sigc++-2.0/sigc++/signal_base.h:27,
                 from /usr/include/sigc++-2.0/sigc++/signal.h:8,
                 from /usr/include/sigc++-2.0/sigc++/sigc++.h:86,
                 from /usr/include/glibmm-2.4/glibmm/thread.h:51,
                 from /usr/include/glibmm-2.4/glibmm.h:87,
                 from /usr/include/giomm-2.4/giomm.h:23,
                 from /home/crefrod/RNS/src/GUI/Interface.cpp:5:
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h: In instantiation of ‘typename sigc::adaptor_functor<T_functor>::deduce_result_type<T_arg1>::type sigc::adaptor_functor<T_functor>::operator()(T_arg1) const [with T_arg1 = const Gtk::StateType&; T_functor = sigc::bound_mem_functor0<void, Interface>; typename sigc::adaptor_functor<T_functor>::deduce_result_type<T_arg1>::type = void]’:
/usr/include/sigc++-2.0/sigc++/functors/slot.h:142:20:   required from ‘static T_return sigc::internal::slot_call1<T_functor, T_return, T_arg1>::call_it(sigc::internal::slot_rep*, sigc::type_trait_take_t<T_arg3>) [with T_functor = sigc::bound_mem_functor0<void, Interface>; T_return = void; T_arg1 = Gtk::StateType; sigc::type_trait_take_t<T_arg3> = const Gtk::StateType&]’
/usr/include/sigc++-2.0/sigc++/functors/slot.h:149:37:   required from ‘static void* (* sigc::internal::slot_call1<T_functor, T_return, T_arg1>::address())(void*) [with T_functor = sigc::bound_mem_functor0<void, Interface>; T_return = void; T_arg1 = Gtk::StateType; sigc::internal::hook = void* (*)(void*)]’
/usr/include/sigc++-2.0/sigc++/functors/slot.h:584:90:   required from ‘sigc::slot1<T_return, T_arg1>::slot1(const T_functor&) [with T_functor = sigc::bound_mem_functor0<void, Interface>; T_return = void; T_arg1 = Gtk::StateType]’
/usr/include/sigc++-2.0/sigc++/functors/slot.h:1731:26:   required from ‘sigc::slot<T_return, T_arg1, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil>::slot(const T_functor&) [with T_functor = sigc::bound_mem_functor0<void, Interface>; T_return = void; T_arg1 = Gtk::StateType]’
/home/crefrod/RNS/src/GUI/Interface.cpp:38:103:   required from here
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:89:30: error: no match for call to ‘(sigc::bound_mem_functor0<void, Interface>) (const Gtk::StateType&)’
     { return functor_(_A_arg1); }
                              ^
In file included from /usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:9:0,
                 from /usr/include/sigc++-2.0/sigc++/functors/slot.h:7,
                 from /usr/include/sigc++-2.0/sigc++/signal_base.h:27,
                 from /usr/include/sigc++-2.0/sigc++/signal.h:8,
                 from /usr/include/sigc++-2.0/sigc++/sigc++.h:86,
                 from /usr/include/glibmm-2.4/glibmm/thread.h:51,
                 from /usr/include/glibmm-2.4/glibmm.h:87,
                 from /usr/include/giomm-2.4/giomm.h:23,
                 from /home/crefrod/RNS/src/GUI/Interface.cpp:5:
/usr/include/sigc++-2.0/sigc++/functors/mem_fun.h:1786:12: note: candidate: T_return sigc::bound_mem_functor0<T_return, T_obj>::operator()() const [with T_return = void; T_obj = Interface]
   T_return operator()() const
            ^
/usr/include/sigc++-2.0/sigc++/functors/mem_fun.h:1786:12: note:   candidate expects 0 arguments, 1 provided
In file included from /usr/include/sigc++-2.0/sigc++/functors/slot.h:7:0,
                 from /usr/include/sigc++-2.0/sigc++/signal_base.h:27,
                 from /usr/include/sigc++-2.0/sigc++/signal.h:8,
                 from /usr/include/sigc++-2.0/sigc++/sigc++.h:86,
                 from /usr/include/glibmm-2.4/glibmm/thread.h:51,
                 from /usr/include/glibmm-2.4/glibmm.h:87,
                 from /usr/include/giomm-2.4/giomm.h:23,
                 from /home/crefrod/RNS/src/GUI/Interface.cpp:5:
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:89:30: error: return-statement with a value, in function returning 'void' [-fpermissive]
     { return functor_(_A_arg1); }
                              ^

One more strange thing is why the compiler throws the error on the second sigc::mem_fun call. Is it just how it works or it has something to do with that fact that the first call is done on the pointer and the second on the object itself?

1

There are 1 answers

0
Ichthyo On

The reason is quite obvious: Gtk::Widget::signal_state_changed() takes and delivers an argument, but you try to connect it to a slot with zero arguments.

Quoting from the documentation

Slot Prototype: void on_my_state_changed(Gtk::StateType previous_state)

Btw, this docu also points out that this slot is deprecated and you should use another slot instead:

on_my_state_flags_changed(Gtk::StateFlags previous_state_flags)

Anyway, to fix this kind of error: make your handler function take the correct number and type of arguments.