у меня есть libsigc++
сигнал, который подключен к лямбде с ++ 11.
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;
Это дает ошибку:
пустое значение не игнорируется, как должно быть
Возможен ли такой способ использования с лямбдами?
Смотрите упоминание 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
}
Надеюсь, мы сделаем это ненужным в будущих версиях libsigc ++ только для C ++ 11.
Вы, вероятно, захотите использовать sigc :: track_obj () тоже: https://developer.gnome.org/libsigc++/unstable/group__track__obj.html#details
Лунг Джин предлагает решение в эта новостная группа.
Просто поместите [этот код] в заголовок и включите его, когда хотите использовать
лямбды. Это также позволяет вам бросить std :: function, boost :: function или любой другой
другой объект с соответствующим оператором () в sigc :: сигналов, так как
sigc :: slot радостно оборачивает их сейчас.Он по-прежнему не работает с классами, которые имеют перегруженный оператор (), но вы
всегда можно использовать лямбду для этих случаев.
Код:
#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;
};
}
Было бы здорово, если бы кто-то мог объяснить, почему это работает, так как я хотел бы изучить здесь механику игры.