Название: Signal/Slot rvalue Отправлено: AlphaGh0St от Март 08, 2016, 19:52 Всем привет!
После переустановки винды и установки нового QtCreator'a 3.6.0 c Qt 5.5.1, по лбу мне ударили грабли, которых я никак не ожидал. Набросал простенький код с целью демонстрации проблемы. В чём суть: Есть некий класс class Object; Сигналим им по ссылке и принимаем в слоте по ссылке. Ссылка не константная, т.к. объект модифицируется в слоте. Код: Q_SIGNALS: Раньше этот код собирался и работал нормально. Сейчас же вылетает такой сюрприз: Цитировать ошибка: no matching function for call to 'MainWindow::ObjSig(Object)' Оказывается, НЕТ такой функции, и, с какой-то радости, теперь передача идёт по значению, а ссылки вот вроде бы как, компилятор, и не заметил случайно.candidate is: void MainWindow::ObjSig(Object&) note: no known conversion for argument 1 from 'Object' to 'Object&' Погуглив, выяснил, что теперь нужно использовать семантику перемещения, а описанный выше код уже не корректен. Ну ОК. Переделал: Код: Q_SIGNALS: Цитировать // в мос_файле case 0: _t->ObjSig((*reinterpret_cast< Object(*)>(_a[1]))); break; case 1: _t->OnObjSig((*reinterpret_cast< Object(*)>(_a[1]))); break; In static member function 'static void MainWindow::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)': ошибка: cannot bind 'Object' lvalue to 'Object&&' In file included from debug\moc_mainwindow.cpp:9:0: initializing argument 1 of 'void MainWindow::ObjSig(Object&&)' ошибка: cannot bind 'Object' lvalue to 'Object&&' In file included from debug\moc_mainwindow.cpp:9:0: initializing argument 1 of 'void MainWindow::OnObjSig(Object&&)' Я морально истощён и уже просто не знаю, что делать, кроме как биться об стену головой. Гугл, как частенько бывает, оказался бесполезным. Как можно решить эту проблему? Благодарю. Название: Re: Signal/Slot rvalue Отправлено: ViTech от Март 09, 2016, 14:18 Вы уверены, что в данном случае, правильно используете сигнал-слот взаимодействие? Подходит ли оно для того, чтобы изменять объект по ссылке?
Оказывается, НЕТ такой функции, и, с какой-то радости, теперь передача идёт по значению, а ссылки вот вроде бы как, компилятор, и не заметил случайно. Может компилятор как раз и заметил, и разработчики, написав такую сигнатуру для метода, указывают, что можно в него передавать, а что нельзя. Синтаксис С++11 позволяет лучше это делать. Например, объект с сигналом ObjSig и объект со слотом OnObjSig находятся в разных потоках. Что произойдёт в этом OnObjSig, когда дело дойдёт до обращения к Object& obj по ссылке? Название: Re: Signal/Slot rvalue Отправлено: Igors от Март 09, 2016, 14:54 А почему не так
Код Вообще - если передается по неконстантной ссылке, то ожидается изменение этого параметра которое, наверное, вызывающий будет использовать. А у Вас другая логика вызывающего, тогда уж объявляйте константной ссылкой Название: Re: Signal/Slot rvalue Отправлено: AlphaGh0St от Март 10, 2016, 01:13 Так можно, и это сработает.
Код: Object temp(0, "test"); Просто передаём объект по ссылке и нас уже не интересует, что с ним будет и каким модификациям он будет подвержен. Потому так спокойно передаю и не беспокоюсь. Проблема остаётся открытой. Если кто-нибудь сталкивался с подобным и нашёл решение, поделитесь им, пожалуйста. Название: Re: Signal/Slot rvalue Отправлено: AlphaGh0St от Март 10, 2016, 01:18 Забыл сказать в предыдущем сообщении. Собственно, верное замечание, что в данном случае следует передавать константной ссылкой. Но если передавать константной ссылкой, разве можно будет проводить какие-то модификации над переданным объектом?
Название: Re: Signal/Slot rvalue Отправлено: Racheengel от Март 10, 2016, 02:24 Забыл сказать в предыдущем сообщении. Собственно, верное замечание, что в данном случае следует передавать константной ссылкой. Но если передавать константной ссылкой, разве можно будет проводить какие-то модификации над переданным объектом? const_cast еще никто не запрещал :) Название: Re: Signal/Slot rvalue Отправлено: Bepec от Март 10, 2016, 08:13 Вообще очень опасная ситуация возникает при таком подходе, мало того, она как ружьё, заряженное на стенке - выстрелит обязательно. Никто не знает когда и куда дойдёт сигнал, сколько получателей и какие потоки.
Я б советовал поменять архитектурку. Название: Re: Signal/Slot rvalue Отправлено: Авварон от Март 10, 2016, 09:50 Яб посоветовал почитать стандарт и узнать, что rvalue не приводится к неконст ссылке, а компилятор, позволяющий делать так, стоит выкинуть на помойку (да, я про студию)
Название: Re: Signal/Slot rvalue Отправлено: Igors от Март 10, 2016, 11:47 Просто передаём объект по ссылке и нас уже не интересует, что с ним будет и каким модификациям он будет подвержен. Потому так спокойно передаю и не беспокоюсь. А это логика передачи по значениюПроблема остаётся открытой. Если кто-нибудь сталкивался с подобным и нашёл решение, поделитесь им, пожалуйста. Похоже Вы ищете пятый угол. Пример без всяких слот-сигналовКод Т.е. так нельзя по правилам языка Код Как известно смысл передачи по константой ссылке двоякий - может быть временный объект или нет. Ну и выберите то что соответствует логике Вашей задачи. А то вызываемый видит одно, вызывающий другое - зачем пытаться этого достичь? Если нужны оба варианта - заведите 2 сигнала, это правильно. Название: Re: Signal/Slot rvalue Отправлено: ViTech от Март 10, 2016, 12:21 Но не хочу так делать исключительно из эстетических соображений. Мне однострочники больше нравятся. Подозреваю, что с таким спокойствием вам ещё много грабель предстоит встретить :).Просто передаём объект по ссылке и нас уже не интересует, что с ним будет и каким модификациям он будет подвержен. Потому так спокойно передаю и не беспокоюсь. Цитата: AlphaGh0St Собственно, верное замечание, что в данном случае следует передавать константной ссылкой. Но если передавать константной ссылкой, разве можно будет проводить какие-то модификации над переданным объектом? Можно поинтересоваться, зачем в слоте модифицировать объект, переданный из сигнала вообще, и по ссылке в частности? И ещё раз предлагаю подумать. Допустим, всё собралось так, как вы хотите и объект передаётся по ссылке. Пусть всё даже происходит в одном потоке. Если мы соединим сигнал с двумя слотами, первый слот модифицирует объект, то что получит второй слот: исходный объект из сигнала или с модификациями из первого слота? Название: Re: Signal/Slot rvalue Отправлено: kambala от Март 10, 2016, 12:28 как-то бессмысленно модифицировать временный объект, созданный в однострочнике, разве нет?
Название: Re: Signal/Slot rvalue Отправлено: Racheengel от Март 10, 2016, 13:02 Если основная идея - модифицировать объект в слоте... то надо быть уверенным, что это единственный слот, связанный с данным сигналом. Иначе последствия могут быть не очень предсказуемы :)
Ну и используйте поинтер, в самом деле. |