Re[11]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: rg45 СССР  
Дата: 07.03.24 20:34
Оценка:
Здравствуйте, Marty, Вы писали:

R>>Да добавь просто определения-пустышки вместо "default".


M>Что значит — пустышки?


Попробуй добавить весь джентльменский набор:

struct IObject
{
   IObject() = default;
   IObject(const IObject&) = default;
   IObject& operator = (const IObject&) = default;

   IObject(IObject&&){}
   IObject& operator = (IObject&&) { return *this; }

   virtual ~IObject() {}

}; // struct IObject


Если после этого проблема уйдет, то попробуй и конструктор и оператор перемещения просто объявить default.

Но это на правах костыля. По идее все должно и так работать. Похоже-таки на баг msvc.
--
Справедливость выше закона. А человечность выше справедливости.
Re[9]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 20:34
Оценка:
Здравствуйте, rg45, Вы писали:

R>Так что наличие пользовательского деструктора в базовом классе не должно препятствовать генерации конструктора перемещения в производном классе. Конструктор же перемещения базового класса не объявляется удаленным, он просто не генерируется компилятором. При этом конструктор перемещения производного класса может спокойно воспользоваться конструктором копирования базового. Действительно похоже на баг MSVC, причем характерный для отдельной версии.


У меня есть и в финальном классе деструктор.

И не очень понятно, чем наличие деструктора мешает перемещению, он же при этом не должен же использоваться
Маньяк Робокряк колесит по городу
Re[9]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: andrey.desman  
Дата: 07.03.24 20:41
Оценка:
Здравствуйте, rg45, Вы писали:

R>Да, но там внизу есть еще такая приписочка:


R>

R>[ Note: When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor. — end note]


Это то, что у него и происходит — ругается, что не может скопировать.

R>Так что наличие пользовательского деструктора в базовом классе не должно препятствовать генерации конструктора перемещения в производном классе.


Деструктор в производном объявлен.

R>Конструктор же перемещения базового класса не объявляется удаленным, он просто не генерируется компилятором. При этом конструктор перемещения производного класса может спокойно воспользоваться конструктором копирования базового. Действительно похоже на баг MSVC, причем характерный для отдельной версии.


Да, но здесь не оно.
Re[12]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 20:43
Оценка:
Здравствуйте, rg45, Вы писали:

M>>Что значит — пустышки?


R>Попробуй добавить весь джентльменский набор:


Добавил не весь, только перемещение

R>
R>struct IObject
R>{
R>   IObject(IObject&&){}
R>   IObject& operator = (IObject&&) { return *this; }

R>}; // struct IObject
R>


Только я сделал в конечном классе, где виртуальный деструктор переопределён
Заработало.

Сделал = default — заработало


R>Если после этого проблема уйдет, то попробуй и конструктор и оператор перемещения просто объявить default.


R>Но это на правах костыля. По идее все должно и так работать. Похоже-таки на баг msvc.



Потом подумал, может ты таки имел в виду самый базовый класс, где один виртуальный деструктор объявлен. Объявил default весь набор. Убрал в финальном классе. Не прокатило.
Маньяк Робокряк колесит по городу
Re[9]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: andrey.desman  
Дата: 07.03.24 20:44
Оценка:
Здравствуйте, Marty, Вы писали:

M>Виноват

M>И что делать, если деструктор есть? Кроме как явно описать конструктор/оп= перемещения?

Явно задекларировать его как default. Но вроде как у тебя все равно же явные телодвижения нужны на перемещение? Timer id переместить в новый объект, в старом занулить, не?
Re[10]: Отсутствующий конструктор копирования в MSVC2019 вызы
От: rg45 СССР  
Дата: 07.03.24 20:46
Оценка:
Здравствуйте, Marty, Вы писали:

M>И не очень понятно, чем наличие деструктора мешает перемещению, он же при этом не должен же использоваться


Ну, с какой целью генерацию конструктора перемещения поставили в зависимость деструктору, это мне сложно объяснить. Но, с другой стороны, блокировка генерации конструктора не означает запрета семантики перемещения. Должна быть возможность открыть конструктор перемещения, просто объявив его как default. И как показывает практика, на других компиляторах это работает. И даже на msvc, более поздних версий.
--
Справедливость выше закона. А человечность выше справедливости.
Re[10]: Отсутствующий конструктор копирования в MSVC2019 выз
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.03.24 20:47
Оценка:
Здравствуйте, andrey.desman, Вы писали:

M>>Виноват

M>>И что делать, если деструктор есть? Кроме как явно описать конструктор/оп= перемещения?

AD>Явно задекларировать его как default.


Так работает, да.


AD>Но вроде как у тебя все равно же явные телодвижения нужны на перемещение? Timer id переместить в новый объект, в старом занулить, не?


Точно, мой косяк

Кстати, а есть рекомендации ведущих собаководов, как правильно писать move ctor/move op=?


UPD
Написал так:
  Скрытый текст
struct WindowTimerImpl : public IWindowTimer
{

    HWND         hWnd           = 0;
    UINT_PTR     idTimerEvent   = 0;
    timeout_t    timerTimeoutMs = 0;
    bool         running        = false;


    //WindowTimerImpl(HWND h, UINT_PTR id) : hWnd(h), idTimerEvent(id) {}

    WindowTimerImpl(HWND h, UINT_PTR id, timeout_t timeoutMs, bool bRunning) : hWnd(h), idTimerEvent(id), timerTimeoutMs(timeoutMs), running(bRunning)
    {
        if (running)
        {
            restart();
        }
    }

    WindowTimerImpl(WindowTimerImpl&& other)
    : hWnd          (std::exchange(other.hWnd, (HWND)0))
    , idTimerEvent  (std::exchange(other.idTimerEvent, 0u))
    , timerTimeoutMs(std::exchange(other.timerTimeoutMs, 0u))
    , running       (std::exchange(other.running, false))
    {
    }

    WindowTimerImpl& operator=(WindowTimerImpl&& other)
    {
        hWnd           = std::exchange(other.hWnd, (HWND)0);
        idTimerEvent   = std::exchange(other.idTimerEvent, 0u);
        timerTimeoutMs = std::exchange(other.timerTimeoutMs, 0u);
        running        = std::exchange(other.running, false);
        return *this;
    }
};


Но, по идее, у меня есть значения по умолчанию, или как такая inplace инициализация называется? По идее, mctor = default и наличия такой инициализации должно хватать для генерации того, что мне пришлось ручками натоптать, не?
Маньяк Робокряк колесит по городу
Отредактировано 07.03.2024 21:09 Marty . Предыдущая версия . Еще …
Отредактировано 07.03.2024 20:59 Marty . Предыдущая версия .
Re[13]: Отсутствующий конструктор копирования в MSVC2019 выз
От: rg45 СССР  
Дата: 07.03.24 20:57
Оценка:
Здравствуйте, Marty, Вы писали:

M>Потом подумал, может ты таки имел в виду самый базовый класс, где один виртуальный деструктор объявлен. Объявил default весь набор. Убрал в финальном классе. Не прокатило.


Да похоже я просто запутался во фрагментах кода и что-то сказал невпопад.

Ну общий принцип такой — объявляешь деструктор — объяви и конструктор перемещения (возможно, как default).

Но нужно помнить, что объявление конструтора перемещения удаляет копирующие конструктор и присваивание. Именно объявляет как delete, а не просто препятствует их автоматической генерации.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 07.03.2024 21:00 rg45 . Предыдущая версия .
Re[11]: Отсутствующий конструктор копирования в MSVC2019 выз
От: rg45 СССР  
Дата: 07.03.24 21:09
Оценка:
Здравствуйте, Marty, Вы писали:

M>Кстати, а есть рекомендации ведущих собаководов, как правильно писать move ctor/move op=?


Не знаю, как там собаководы, но лично я стараюсь проектировать так, чтоб минимизировать необходимость определять самому специальные функции-члены. Это для меня как один из критериев качества дизайна. При этом необходимо помнить зависимости между ними. Вот хорошая картинка на эту тему:

--
Справедливость выше закона. А человечность выше справедливости.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.