Russian Qt Forum
Ноябрь 22, 2024, 04:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 ... 6 7 [8] 9   Вниз
  Печать  
Автор Тема: C++ Object Token Library  (Прочитано 58806 раз)
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #105 : Февраль 13, 2020, 09:52 »

К сожалению, далеко не весь ф-ционал реализованный "в лоб" достижим с Вашей либой. Конечно это нормально (есть область применения и.т.п.), но все-таки хотелось бы.

Правильно, есть область применения. Библиотека не претендует на исполнение всех желаний всех желающих Улыбающийся.
Записан

Пока сам не сделаешь...
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #106 : Февраль 13, 2020, 11:30 »

Валидность экземпляра значения после move зависит от операции, обычно это move constructor и move assignment operator, и в них определяется (указывается в документации, если она есть Улыбающийся), в каком состоянии останется объект-источник. ...

Технически конечно всё зависит от реализации. Можно запрограммировать вообще любое действие. Можно и операторы переопределить и получить совершенно другую математику. Но на действие бинарного оператора "+" предполагается реализация понятия суммы, на действие бинарного оператора "-" - реализация разности, на метод "swap" - обмен значениями, оператор присвоения "=" с rvalue справа предполагает перенос значения справа налево и оставление правой части в частично сформированном виде не пригодном для полноправного использования.

Стандарт вводит такие положения:

Цитировать
20.5.5.15 Moved-from state of library types [lib.types.movedfrom]
Objects of types defined in the C++ standard library may be moved from ( 15.8 ). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

20.3.25 [defns.valid]
valid but unspecified state
value of an object that is not specified except that the object’s invariants are met and operations on the object behave as specified for its type
[Example: If an object x of type std::vector<int> is in a valid but unspecified state, x.empty() can be called unconditionally, and x.front() can be called only if x.empty() returns false. — end example ]

Не все типы могут иметь какое-то дефолтное валидное состояние, в которое можно перейти после операции перемещения. Вполне можно использовать опцию (Unless otherwise specified) и явно указать невозможность использования для таких типов, что на самом деле в общем виде логически и подразумевается.

Может дать предложение по изменению стандарта  Смеющийся Смеющийся Смеющийся ?

Цитировать
20.5.5.15 Moved-from state of library types [lib.types.movedfrom]
... Unless otherwise specified, such moved-from objects shall be placed in a unspecified but destructible state.
« Последнее редактирование: Февраль 13, 2020, 11:36 от ssoft » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #107 : Февраль 13, 2020, 11:46 »

Не все типы могут иметь какое-то дефолтное валидное состояние, в которое можно перейти после операции перемещения. Вполне можно использовать опцию (Unless otherwise specified) и явно указать невозможность использования для таких типов, что на самом деле в общем виде логически и подразумевается.

Согласен. По умолчанию можно предупреждать о доступе к moved-from объекту, но для некоторых случаев делать исключения, чтобы чрезмерные запреты не приводили к неудобству. Я к тому, что не всё так однозначно, как "надо всё запретить и не пущать" Улыбающийся. Касательно not_null поведение анализатора по умолчанию и будет срабатывать.

Кстати, нужны ещё диагностики, чтобы доступ к optional-like объекту осуществлялся только после проверки, что в нём что-то есть.

Может дать предложение по изменению стандарта  Смеющийся Смеющийся Смеющийся ?

Цитировать
20.5.5.15 Moved-from state of library types [lib.types.movedfrom]
... Unless otherwise specified, such moved-from objects shall be placed in a unspecified but destructible state.

Судя по тому, что Herb Sutter говорит про "C++ gets something along the lines of the relocation / destructive move semantics proposals, where roughly "relocation/destructive-move leaves an object that is guaranteed to be no longer used" or similar (in those proposals, including even its dtor won't be called)", значит что-то ещё думают в этом направлении, может и формулировки поменяют. Но не скоро Улыбающийся.
« Последнее редактирование: Февраль 13, 2020, 12:43 от ViTech » Записан

Пока сам не сделаешь...
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #108 : Февраль 13, 2020, 12:36 »

Объяснения типа "ну это ж legacy", тем более "да они не знают" явно несостоятельны.

И тем не менее это так https://lists.qt-project.org/pipermail/development/2020-January/038544.html

А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #109 : Февраль 13, 2020, 15:31 »

А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?
Вооот
Цитировать
..хорошо хоть задумываться начали
(как один тут говорил Улыбающийся). Полагаю что точно так же как сейчас, std здесь ничего не дает

По умолчанию можно предупреждать о доступе к moved-from объекту, но для некоторых случаев делать исключения, чтобы чрезмерные запреты не приводили к неудобству.
Откуда возникают такие сложности, не надуманы ли они?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #110 : Февраль 13, 2020, 15:37 »

А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?

Например, так
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #111 : Февраль 13, 2020, 17:27 »

А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?

Например, так

Понятно, что это наброски, подмазали косметикой, и придираться к этому не стоит...

Но вот например T* adoptChild(std::unique_ptr<T> child):
Код
C++ (Qt)
template<class T>
T* adoptChild(std::unique_ptr<T> child) {
   child->setParent(this);
   return child.release();
}

Здесь подходящий случай, чтобы использовать gsl::not_null<std::unique_ptr<T>>? Или допустимо, что child может быть nullptr?

Но вообще мне грустно становится... ssoft (и другие разумеется тоже), что думаешь, когда видишь два таких метода рядом?
Код
C++ (Qt)
template<class T>
void adoptChild(T *child);
 
template<class T>
T* adoptChild(std::unique_ptr<T> child);
« Последнее редактирование: Февраль 13, 2020, 18:12 от ViTech » Записан

Пока сам не сделаешь...
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #112 : Февраль 13, 2020, 17:48 »

На том же примере
Код
C++ (Qt)
   heap_unique<Resource> heap_owner_1 = make_unique<Resource>("heap_resource_1");
   weak<Resource>        heap_weak{heap_owner_1.get()};
   ...
   heap_unique<Resource> heap_owner_2 = std::move(heap_owner_1);
Верно ли я понял что heap_weak.get() должен возвращать null после move ?

Неверно. heap_weak связан с heap_resource_1, и он никуда не делся, просто сменился его владелец. Так что heap_weak остался связан с heap_resource_1.

А если бы всё-таки решили в Qt использовать умные указатели и контейнеры std, то как бы хранили список детей (children) для QObject?
Вооот
Цитировать
..хорошо хоть задумываться начали
(как один тут говорил Улыбающийся). Полагаю что точно так же как сейчас, std здесь ничего не дает

Для такой огромной кодовой базы родом из 90-х, умные указатели действительно мало что дадут. Полагаю, Qt до скончания своих веков будет на голых указателях жить. Если менять на умные нормально, там много чего переделывать придётся, и это будет уже совсем другой Qt. Но это не значит, что надо опустить руки и ничего не делать Улыбающийся.

По умолчанию можно предупреждать о доступе к moved-from объекту, но для некоторых случаев делать исключения, чтобы чрезмерные запреты не приводили к неудобству.
Откуда возникают такие сложности, не надуманы ли они?

Может и надуманы, но это надо проверить Улыбающийся. А для этого надо подумать ещё лучше.
Записан

Пока сам не сделаешь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #113 : Февраль 13, 2020, 18:38 »

Понятно, что это наброски, подмазали косметикой, и придираться к этому не стоит...

Но вот например T* adoptChild(std::unique_ptr<T> child):
Код
C++ (Qt)
template<class T>
T* adoptChild(std::unique_ptr<T> child) {
   child->setParent(this);
   return child.release();
}

Здесь подходящий случай, чтобы использовать gsl::not_null<std::unique_ptr<T>>? Или допустимо, что child может быть nullptr?

Да, вполне. Ну или метод должен на nullptr проверять.

Но вообще мне грустно становится... ssoft (и другие разумеется тоже), что думаешь, когда видишь два таких метода рядом?
Код
C++ (Qt)
template<class T>
void adoptChild(T *child);
 
template<class T>
T* adoptChild(std::unique_ptr<T> child);

Первый метод должен возвращать T * естессно чтобы код выглядел унифицированно.
У данного решения есть огромный плюс - оно на уровне сорцов совместимо со старым кодом. Что позволяет объявить конструкторы от QObject * и setParent() deprecated и сказать всем - юзайте parent->adoptChild(child) вместо child->setParent(parent). Первый метод позволяет сделать замену тривиальной.
Второй, после того, как произошла замена, позволяет потихоньку добавить современного с++.
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #114 : Февраль 14, 2020, 11:19 »

Но вообще мне грустно становится... ssoft (и другие разумеется тоже), что думаешь, когда видишь два таких метода рядом?

Если честно - полное отсутствие каких-либо мыслей)). Это какое-то изнасилование unique_ptr ( использовали child->setParent(this); и выбросили child.release(); ).
Нужно сначала понять преследуемую цель применения здесь умных указателей. Если для внутреннего использования, чтобы с исключениями можно нормально работать было - это одно; если добавить заплатки для тех, кто использует умные указатели - другое; если еще что-то - то третье.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #115 : Февраль 14, 2020, 12:19 »

Очевидно, что цель патча не переписать внутренности QObject а продемонстрировать API и то, что оно совместимо с текущим кодом. Это как бы важнее того как "у ей внутре" оно реализовано. Да, там будет просто мув юника во внутренний вектор (и это тоже очевидно), но это деталь реализации совершенно не важная на данный момент
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #116 : Февраль 14, 2020, 14:29 »

У QPointer есть юзкейзы, но они настолько редкие что добавлять это в стандартную библиотеку нафиг не уперлось (то есть в той же Qt QPointer юзается ровно по той причине что все виджеты в главном потоке и "продлять жизнь" не надо). Но ВНЕЗАПНО не все с++ погромисты пишут ГУИ тулкит и не у всех есть требование "только в главном потоке".

А если бы QPointer был потокобезопасным, у него было бы больше юзкейсов? Насколько активно этим бы пользовались?
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #117 : Февраль 14, 2020, 15:01 »

А если бы QPointer был потокобезопасным,
Кстати - а можно код Вашей реализации move? (ну или обеспечивающего конструктора). Хочу посмотреть как там с (без)опасностью. Спасибо
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #118 : Февраль 14, 2020, 15:21 »

Кстати - а можно код Вашей реализации move? (ну или обеспечивающего конструктора). Хочу посмотреть как там с (без)опасностью. Спасибо

Вы какие-то неприличные вопросы задаёте для open source библиотеки под MIT лицензией расположенной на популярном хостинге репозиториев Улыбающийся. CppOtl examples, пример Car как раз про многопоточность. Можете скачать,  рассматривать и пытать как душе угодно. Если коротко, то move в токенах такой же, как в умных указателях std.
Записан

Пока сам не сделаешь...
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #119 : Февраль 19, 2020, 12:03 »

Свежак от Herb Sutter: Move, simply.

То что что-то остается в валидном состоянии - это всего лишь удобство реализации, просто полное уничтожение экземпляра может быть нерациональным с точки зрения производительности, для таких экземпляров вводят термин "частично сформированный". В общем случае move - это способ показать явно, что более данный экземпляр значения использован не будет (указание намерения уничтожения до окончания области видимости). Валидность экземпляра значения после move не гарантируется. Это, конечно, не является обязательным требованием, однако в общем случае лучше делать так, чтобы не иметь логических разночтений.

У Герба другое мнение Улыбающийся:
Цитировать
...
Can a given type document that moving from an object always changes its state? or changes it to a known state?

Yes, move is just another non-const function. Any non-const function can document when and how it changes the object’s state, including to specify a known new state as a postcondition if it wants. For example, unique_ptr‘s .release() function is guaranteed to set the object to null — just as its move functions are guaranteed to set the source object to null.

...

Does “but unspecified” mean the object’s invariants might not hold?

No. In C++, an object is valid (meets its invariants) for its entire lifetime, which is from the end of its construction to the start of its destruction. Moving from an object does not end its lifetime, only destruction does, so moving from an object does not make it invalid or not obey its invariants.

If any non-const function on an object (including moving from it) makes the object invalid, the function has a bug.
...

Там же обсуждение в комментах. Понравился такой Улыбающийся:
Цитировать
steve heller

If that’s the simple explanation, I don’t want to see the complex one.

Ещё на reddit:
Move, simply – Sutter’s Mill.
Сразу же появился "Наш ответ Чемберлену": move, even more simply.

Ещё про перемещение:
Object relocation in terms of move plus destroy.
move = bitcopies.
« Последнее редактирование: Февраль 19, 2020, 13:27 от ViTech » Записан

Пока сам не сделаешь...
Страниц: 1 ... 6 7 [8] 9   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.363 секунд. Запросов: 23.