2

我有一个libsigc++连接到 c++11 lambda 的信号。

sigc::signal<void, std::string> foo;

foo.connect([](string s) { cout << s << endl; });

foo.emit(string("Hello"));

我想将信号的返回类型从void更改为非无效

sigc::signal<int, std::string> foo;

foo.connect([](string s) { return s.size(); });

cout << foo.emit(string("Hello")) << endl;

这给出了一个错误:

void 值没有被忽略,因为它应该被忽略

lambda 是否可以使用这种使用模式?

4

2 回答 2

2

请参阅此处提到的 SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE:https ://developer.gnome.org/libsigc++/stable/group__slot.html#details

您只需要将其放在源文件顶部附近:

namespace sigc {
  SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
}

希望我们将在未来的仅限 C++11 的 libsigc++ 版本中避免这种情况。

您可能也想使用 sigc::track_obj():https ://developer.gnome.org/libsigc++/unstable/group__track__obj.html#details

于 2015-07-09T20:34:10.037 回答
1

Loong Jin 在此新闻组发帖中提供了解决方案。

只需将 [此代码] 放在某个标题中,并在您想使用 lambda 时将其 #include 即可。它还允许您在 sigc::signals 上使用适当的 operator() 抛出 std::function、boost::function 或任何其他对象,因为 sigc::slot 现在很高兴地将它们包装起来。

它仍然不适用于具有重载 operator() 的类,但您始终可以在这些情况下使用 lambda。

编码:

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

如果有人能解释为什么这样做会很好,因为我想在这里学习游戏机制。

于 2014-10-20T17:16:45.180 回答