использовать лямбду в связи с библиотекой 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 ++ 🙂

5

Решение

Для 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, но я понятия не имею, насколько хорошо это работает.

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

5

Другие решения

Я нашел следующий код, который выполняет работу. Я понятия не имею, как это взаимодействует с библиотекой 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 теперь может обрабатывать lambas без какого-либо дополнительного пользовательского кода. Приведенный выше код должен быть удален, если используются текущие версии.

3

Демо с использованием Пример 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;
}

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

0
По вопросам рекламы [email protected]