Здравствуйте, Marty, Вы писали:
M>Почему он хочет копировать, а не перемещать?
У тебя же перемещение запрещено явно твоим NonCopiable.
Переместить он пытается, но тихо обламывается, потому что всегда можно скопировать если вдруг не прокатило. Далее пытается копировать, но и тут облом. Вот он и говорит, что скопировать не может.
Re: Отсутствующий конструктор копирования в MSVC2019 вызывает ош
Здравствуйте, Marty, Вы писали:
M>Ладно, попробовал вернуть через std::move. Стало ругаться на строчку с ним, но суть осталась та же.
Суть другая. Во время return работает copy elision, copy/move конструкторы не нужны. Обламывается он в момент передачи в make_shared. Как только ты воткнул return std::move, то обламывается уже в момент return.
Разреши мув конструктор, все будет работать.
Re[3]: Отсутствующий конструктор копирования в MSVC2019 вызы
Ну хорошо, а в IObject что? Ты в курсе, что, если ты объявил какой-то конструктор как default, это еще не гарантия того, что этот конструктор будет реально доступен? "default" на раз может реализоваться в "delete", если в классе присутствуют подобъекты(члены, базовые классы, члены базовых классов...) с явно или неявно удаленным конструктором.
Смотри, как получается, ты ждешь, что тебе помогут, не показывая всего кода. Так можно потратить уйму времени с нулевым результатом.
Я бы предложил тебе поработать над минимизированным примером, воспроизводящем проблему, который можно было бы загрузить в какой-нибудь онлайн компилятор. И очень вероятно, что ошибку ты найдешь сам, в процессе работы над этим примером.
Здравствуйте, andrey.desman, Вы писали:
M>>Почему он хочет копировать, а не перемещать?
AD>У тебя же перемещение запрещено явно твоим NonCopiable. AD>Переместить он пытается, но тихо обламывается, потому что всегда можно скопировать если вдруг не прокатило. Далее пытается копировать, но и тут облом. Вот он и говорит, что скопировать не может.
Разве? Я думал, что = default говорит использовать ту версию, которую он сам сгенерил, не?
У меня в NonCopiable copy ctor/op= запрещены
Здравствуйте, andrey.desman, Вы писали:
M>>Ладно, попробовал вернуть через std::move. Стало ругаться на строчку с ним, но суть осталась та же.
AD>Суть другая. Во время return работает copy elision, copy/move конструкторы не нужны. Обламывается он в момент передачи в make_shared. Как только ты воткнул return std::move, то обламывается уже в момент return.
AD>Разреши мув конструктор, все будет работать.
R>Ну хорошо, а в IObject что? Ты в курсе, что, если ты объявил какой-то конструктор как default, это еще не гарантия того, что этот конструктор будет реально доступен? "default" на раз может реализоваться в "delete", если в классе присутствуют подобъекты(члены, базовые классы, члены базовых классов...) с явно или неявно удаленным конструктором.
R>Смотри, как получается, ты ждешь, что тебе помогут, не показывая всего кода. Так можно потратить уйму времени с нулевым результатом.
R>Я бы предложил тебе поработать над минимизированным примером, воспроизводящем проблему, который можно было бы загрузить в какой-нибудь онлайн компилятор. И очень вероятно, что ошибку ты найдешь сам, в процессе работы над этим примером.
Ну, пока решилось, были ошибочные представления о реализации make_shared в MSVC2019, из-за чего я пошел не тем путём
А, вспомнил, почему так получилось. Был код с make_shared, который в MSVC2019 не собирался, а у коллеги в MSVC2022 собирался. Мы поковыряли, и решили, что что-то не так с make_shared в MSVC2019
Здравствуйте, rg45, Вы писали:
M>>Ладно, попробовал вернуть через std::move. Стало ругаться на строчку с ним, но суть осталась та же.
R>Ну у тебя и так здесь rvalue выражение, что ты рассчитываешь получить еще от move?
Я хотел сказать ему: "ну пожалуста-пожалуста, сделай мув"
AD>А,просмотрел, что мув разрешен. Тогда да, что-то не мувается по умолчанию.
Понять бы, что. По всей иерархии наследования никаких полей в классах нет, только чисто виртуальные функции. Ни конструкторов, ни операторов= никакиех нет вообще, только в финальном классе есть конструктор.
А в финальном классе так:
M>Ну, пока решилось, были ошибочные представления о реализации make_shared в MSVC2019, из-за чего я пошел не тем путём
M>А, вспомнил, почему так получилось. Был код с make_shared, который в MSVC2019 не собирался, а у коллеги в MSVC2022 собирался. Мы поковыряли, и решили, что что-то не так с make_shared в MSVC2019
Ну вообще, все, что приходит на вход std::make_shared форвардится в конструкторы объекта создаваемого класса. Конструкторы могут быть разные — копирования, перемещения, преобразования, с одним параметром и с несколькими. Если что-то работает не так, как ожидается, то я стараюсь все такие моменты доводить до полной ясности. Вот когда есть небольшой понятный примерчик, который и там и сям работает, а не работает только на каком-то определенном компиляторе или режиме, вот тогда тогда только можно говорить, что это баг компилятора. А так это просто предположение, а точная причина так и не выяснена пока.
--
Re[4]: Отсутствующий конструктор копирования в MSVC2019 вызывает ош
Здравствуйте, rg45, Вы писали:
R>Вот когда есть небольшой понятный примерчик, который и там и сям работает, а не работает только на каком-то определенном компиляторе или режиме, вот тогда тогда только можно говорить, что это баг компилятора. А так это просто предположение, а точная причина так и не выяснена пока.
Здравствуйте, Marty, Вы писали:
R>>Вот когда есть небольшой понятный примерчик, который и там и сям работает, а не работает только на каком-то определенном компиляторе или режиме, вот тогда тогда только можно говорить, что это баг компилятора. А так это просто предположение, а точная причина так и не выяснена пока.
M>На MSVC не работает так же, как у меня M>https://godbolt.org/z/ba4Pexz3j
#include <memory>
struct A
{
A() = default;
A(A&&) = default;
A(const A&) = delete;
static A Create() {return {}; }
};
A makeA() { return {}; }
int main()
{
const auto sp = std::make_shared<A>(A::Create());
}
Можешь попробовать компильнуть у себя? Если возникнет та же ошибка — тады ой — это однозначно проблема MSVC. Ну а если откомпилится успешно, тогда твое предположение ошибочно, так получается.
Здравствуйте, Marty, Вы писали:
M>На MSVC не работает так же, как у меня
Потому что ты, негодяй, не сказал, что есть деструктор.
If no user-defined move constructors are provided for a class type, and all of the following is true:
there are no user-declared copy constructors;
there are no user-declared copy assignment operators;
there are no user-declared move assignment operators;
there is no user-declared destructor.
Then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).
Re[8]: Отсутствующий конструктор копирования в MSVC2019 вызы
R>Можешь попробовать компильнуть у себя? Если возникнет та же ошибка — тады ой — это однозначно проблема MSVC. Ну а если откомпилится успешно, тогда твое предположение ошибочно, так получается.
Это собралось. Вопрос в том, что не так у меня в том коде, который не компилируется
Здравствуйте, Marty, Вы писали:
R>>Можешь попробовать компильнуть у себя? Если возникнет та же ошибка — тады ой — это однозначно проблема MSVC. Ну а если откомпилится успешно, тогда твое предположение ошибочно, так получается.
M>Это собралось. Вопрос в том, что не так у меня в том коде, который не компилируется
Во-о-от! И я о том же. Я тебе прямо очень-очень советую пробовать минимизировать твой код. Причина обязательно найдется, уверяю тебя.
--
Re[9]: Отсутствующий конструктор копирования в MSVC2019 вызы
Здравствуйте, rg45, Вы писали:
M>>Виноват M>>И что делать, если деструктор есть? Кроме как явно описать конструктор/оп= перемещения?
R>Да добавь просто определения-пустышки вместо "default".
Здравствуйте, andrey.desman, Вы писали:
AD>Потому что ты, негодяй, не сказал, что есть деструктор.
AD>
AD>If no user-defined move constructors are provided for a class type, and all of the following is true:
AD> there are no user-declared copy constructors;
AD> there are no user-declared copy assignment operators;
AD> there are no user-declared move assignment operators;
AD> there is no user-declared destructor.
AD>Then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).
[ 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]
Так что наличие пользовательского деструктора в базовом классе не должно препятствовать генерации конструктора перемещения в производном классе. Конструктор же перемещения базового класса не объявляется удаленным, он просто не генерируется компилятором. При этом конструктор перемещения производного класса может спокойно воспользоваться конструктором копирования базового. Действительно похоже на баг MSVC, причем характерный для отдельной версии.