Russian Qt Forum

Qt => Общие вопросы => Тема начата: TrimS от Февраль 08, 2014, 01:15



Название: проблема с connect & lambda
Отправлено: TrimS от Февраль 08, 2014, 01:15
Вот минимальный код, который у меня воспроизводит проблему:
Код:
void MainController::EstablishConnections()
{
QAction* pAction = lang_action.data();
bool c1 = connect(pAction, &QAction::triggered, []()
{
int k = 0;
++k;
});
}

Переменная c1 нормально устанавливается в true.

Получаю варнинг:
Цитировать
warning C4505: 'QAction::[thunk]: __thiscall QAction::`vcall'{8,{flat}}' }'' : unreferenced local function has been removed

Это почему лямбда то выкусывается?  ???
Если этот акшн  потом привязать к пункту меню - то пункт меню не показывается.
Это как понимать?


Название: Re: проблема с connect & lambda
Отправлено: gil9red от Февраль 08, 2014, 03:07
Функция != слоты :)
О слотах ведь нужно сообщать метакомпилятору, поэтому они и прописываются в классах ( public/private/protected slots ), да и соединение описывается по другому, например: connect( <указатель_на_отправителя>, SIGNAL(<сигнал_отправителя>), <указатель_на_слушателя>, SLOT(<слот_слушателя>) );


Название: Re: проблема с connect & lambda
Отправлено: Serr500 от Февраль 08, 2014, 07:50
В Qt5 можно цеплять лямбды вместо слотов.


Название: Re: проблема с connect & lambda
Отправлено: Hrundel от Февраль 08, 2014, 17:03
А что такое лямбды?


Название: Re: проблема с connect & lambda
Отправлено: lit-uriy от Февраль 08, 2014, 17:10
>А что такое лямбды?
да просто анонимные функции ("здесь, по месту")

http://ru.wikipedia.org/wiki/Анонимная_функция (http://ru.wikipedia.org/wiki/Анонимная_функция)
http://ru.wikipedia.org/wiki/Замыкание_(программирование) (http://ru.wikipedia.org/wiki/Замыкание_(программирование))


Название: Re: проблема с connect & lambda
Отправлено: Johnik от Февраль 08, 2014, 23:11
По теме:
Вот минимальный код, который у меня воспроизводит проблему:
Код:
void MainController::EstablishConnections()
{
QAction* pAction = lang_action.data();
bool c1 = connect(pAction, &QAction::triggered, []()
{
int k = 0;
++k;
});
}

Переменная c1 нормально устанавливается в true.

Получаю варнинг:
Цитировать
warning C4505: 'QAction::[thunk]: __thiscall QAction::`vcall'{8,{flat}}' }'' : unreferenced local function has been removed

Это почему лямбда то выкусывается?  ???
Если этот акшн  потом привязать к пункту меню - то пункт меню не показывается.
Это как понимать?


А выкусывается только тогда, когда вы компилите в "release"?
попробуйте более полезный код прописать в лямбде, оптимизатор такой код просто выкидывает:
Код:
int k = 0;
++k;


Название: Re: проблема с connect & lambda
Отправлено: TrimS от Февраль 08, 2014, 23:35
А выкусывается только тогда, когда вы компилите в "release"?
Нет, в том то и дело, что и в дебаге тоже - хотя не должно. Внутри лямбды было изначально более сложная логика, с захватом this - так что лямбда выкусываться недолжна никак.


Название: Re: проблема с connect & lambda
Отправлено: Johnik от Февраль 08, 2014, 23:56
Лямбдами активно пользуюсь, проблем не возникало. Компилятор MSVC 2010

Если Qt 5.2 у вас, можно попробовать выполнить лямбду в контексте объекта:

Код:
QMetaObject::Connection QObject::connect(const QObject * sender, PointerToMemberFunction signal, const QObject * context, Functor functor, Qt::ConnectionType type) [static]

по поводу warning C4505, пишут что это баг компиляторов MSVC до 2010 включительно. отключить:
Код:
#if defined(_MSC_VER) && (_MSC_VER <= 1600)
#  pragma warning(disable:4505)
#endif
но сомневаюсь, что код после этого заработает


Название: Re: проблема с connect & lambda
Отправлено: TrimS от Февраль 09, 2014, 00:53
Да, у меня Qt 5.2.
Да лямбда изначально была в контексте - тут без разницы.
Давить варнинг не имеет смысла - лямбда выкусывается по факту в любом случае.

Блин, ну как так, что ж это за хрень то такая? Даже нет идей почему - только предположение, что лямбда не копируется а берётся от неё только ссылка - на мой взгляд только так она может выкусываться....


Название: Re: проблема с connect & lambda
Отправлено: Johnik от Февраль 09, 2014, 01:32
а простой код, типа:
Код
C++ (Qt)
#include <iostream>
 
using namespace std;
 
int main()
{
auto l = [] ()
{
cout << "hello";
};
l();
return 0;
}
 
компилится, работает?


Название: Re: проблема с connect & lambda
Отправлено: TrimS от Февраль 09, 2014, 01:54
Да.

Ой, извините, я нашёл ошибку - она была совсем в другом месте. Теперь действительно можно просто задушить варнинг и всё нормально работает. Извините за беспокойство. Спасибо за помощь!


Название: Re: проблема с connect & lambda
Отправлено: Johnik от Февраль 09, 2014, 02:04
а в чем проблема-то была?


Название: Re: проблема с connect & lambda
Отправлено: kambala от Февраль 09, 2014, 02:04
в крайнем случае всегда можно использовать старый добрый слот :)


Название: Re: проблема с connect & lambda
Отправлено: Johnik от Февраль 09, 2014, 02:06
после лямбд, которые проверяются на этапе компиляции, к слотам не очень хочется возвращаться, использую их в крайних случаях.


Название: Re: проблема с connect & lambda
Отправлено: lit-uriy от Февраль 09, 2014, 20:11
Johnik в Qt5 (там где есть лямбды) есть и слоты, которые проверяются при компиляции, но у них есть минусы.


Название: Re: проблема с connect & lambda
Отправлено: Johnik от Февраль 09, 2014, 23:51
Эти слоты я тоже имел ввиду. Какие минусы, я пока не замечал?