7

我想在 gtk++ 中使用与 goocanvas 相关的 lambda 表达式。根据我的理解,这意味着我必须能够将我的 lambda 放入 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 直接与 lambdas 或更好的 gtkmm 一起工作而无需 sigc++ 中间体:-)

4

3 回答 3

6

对于没有参数的 void 返回函数/方法,它非常简单,例如(gcc 4.6、4.7):

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

不幸的是,我无法获得值返回或参数获取方法来编译,并且不得不求助于sigc::mem_fun()这些方法。最近似乎有一些活动可以解决这个问题,例如,这个 commit。如果您有 sigc++ 2.2.11 或更高版本,您可以尝试定义SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE,但我不知道它的效果如何。

同样相关的是这个错误报告

于 2012-12-11T03:32:32.943 回答
3

我发现以下代码可以完成这项工作。我不知道它如何与 sigc++ lib 交互,但我可以将它用于简单的情况。也许其他人可以看看它。

            #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。如果使用任何当前版本,则必须删除上述代码。

于 2012-12-11T07:34:52.033 回答
1

使用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;
}

拉姆达有效。

于 2018-11-29T10:55:22.270 回答