sigC++ с лямбда-ошибкой: значение void не игнорируется, как должно быть
У меня есть 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;
Это дает ошибку:
пустое значение не игнорируется, как должно быть
Возможен ли такой способ использования с лямбдами?
2 ответа
См. Упоминание SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE здесь: https://developer.gnome.org/libsigc++/stable/group__slot.html
Вам просто нужно поместить это в начало вашего исходного файла:
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
Loong Jin предоставляет решение в этой публикации в новостной группе.
Просто поместите [этот код] в заголовок и включите его, когда хотите использовать лямбда-выражения. Это также позволяет вам вызывать 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;
};
}
Было бы здорово, если бы кто-то мог объяснить, почему это работает, так как я хотел бы изучить здесь механику игры.