Использовать лямбду в связи с библиотекой sigc

Я хочу использовать лямбда-выражения в связи с goocanvas в gtk++. Для моего понимания это означает, что я должен быть в состоянии поместить свою лямбду в функтор sigC++.

Я попробовал что-то подобное:

sigc::slot<bool,  const Glib::RefPtr<Goocanvas::Item>& , GdkEventMotion* > slot2=
    [](  const Glib::RefPtr<Goocanvas::Item>& item, GdkEventMotion* ev)->bool
    {
        cout << "Lambda " << endl; return false;
    };

((Glib::RefPtr<Goocanvas::Item>&)item1)->signal_motion_notify_event().connect( slot2);

Но это не скомпилируется.

Есть ли шанс заставить sigc работать с лямбдами или лучше с gtkmm напрямую без промежуточного соединения sigC++:-)

3 ответа

Решение

Я нашел следующий код, который выполняет работу. Я понятия не имею, как это взаимодействует с библиотекой sigC++, но я могу использовать ее для простых случаев. Может быть, кто-то еще может взглянуть на это.

            #include <type_traits>
            #include <sigc++/sigc++.h>
            namespace sigc
            {   
                template <typename Functor>
                    struct functor_trait<Functor, false>
                    {   
                        typedef decltype (::sigc::mem_fun (std::declval<Functor&> (), 
                                    &Functor::operator())) _intermediate;

                        typedef typename _intermediate::result_type result_type;
                        typedef Functor functor_type;
                    };  
            }   

ОБНОВЛЕНИЕ: Libsigc теперь может обрабатывать ламбы без дополнительного пользовательского кода. Приведенный выше код должен быть удален, если используются текущие версии.

Для void, возвращающих функции / методы без аргументов, это довольно просто, например (gcc 4.6, 4.7):

 fileButton.signal_pressed().connect([this]{on_file_button_clicked();});

К сожалению, я не смог получить методы, возвращающие значения или принимающие аргументы для компиляции, и мне пришлось прибегнуть к sigc::mem_fun() для тех. Кажется, в последнее время предпринимаются некоторые действия, чтобы исправить это, например, этот коммит. Если у вас sigC++ версии 2.2.11 или выше, вы можете попробовать определить SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPEНо я понятия не имею, насколько хорошо это работает.

Также связан этот отчет об ошибках.

Демонстрация, использующая пример gtkmm helloworld:

#include "helloworld.h"
#include <iostream>

HelloWorld::HelloWorld()
    : m_button("Hello World")  // creates a new button with label "Hello World".
{
    // Sets the border width of the window.
    set_border_width(10);

    // When the button receives the "clicked" signal, it will call the
    // on_button_clicked() method defined below.
    m_button.signal_clicked().connect(
        sigc::mem_fun(*this, &HelloWorld::on_button_clicked));

    m_button.signal_clicked().connect([=]() { std::cout << "hello lambda\n"; });

    // This packs the button into the Window (a container).
    add(m_button);

    // The final step is to display this newly created widget...
    m_button.show();
}

HelloWorld::~HelloWorld() {}

void HelloWorld::on_button_clicked() {
    std::cout << "hello method" << std::endl;
}

Лямбда работает.

Другие вопросы по тегам