У меня проблема с decltype, которая не работает для vector.
Вектор Eq того же типа, что и holder и itemGrabbed:
item* itemGrabbed;
item* holder;
std::vector<std::vector<item*>> Eq;
Все инициализируется и т.д.
Eq хранит указатели на «унаследованные» объекты — например, объекты из class itemAxe.
Каждый класс item и унаследованные объекты имеют один и тот же конструктор с этим аргументом -> grapicsData:
this->itemGrabbed = new std::remove_pointer<decltype(Eq[x][y]) > ::type{graphicsData};
this->itemGrabbed = new std::remove_pointer<decltype(holder) > ::type{graphicsData};
Я думаю, я мог бы просто пойти с чем-то вроде этого:
item* temp=Eq[x][y];
this->itemGrabbed = new std::remove_pointer<decltype(temp) > ::type{graphicsData};
Но мне было интересно, можно ли обойтись без temp?
Проблема в том, что второй вариант работает, но мне нужно использовать первый. И все это потому, что мне нужны разные операторы присваивания и копирования.
Как я могу этого добиться?
«Вектор Eq того же типа, что и holder и itemGrabbed». -- Нет. Элементы элементов Eq имеют тот же тип, что и две другие переменные, но вектор X не того же типа, что и X. Вы намеревались ссылаться на элементы вместо вектора? Это лучше соответствовало бы вашему коду.
«Интересно, возможно ли это сделать» — Что именно «это»? Вы описали свою настройку и показали некоторый код, но не указали, какова ваша цель. Почему вы используете decltype? Как вы думаете, что вы получите от такого многословия?
Eq[x][y] это именно то, что я пытаюсь использовать в decltype, проблема в том, что decltype мне не подходит
item имеет другую функцию update(), чем itemAxe. Следующий шаг — *this->itemGrabbed = *Eq[x][y];, а позже я назначаю это где-то еще, поэтому мне нужно, чтобы это был точный указатель класса, у меня есть копия и оператор = готов.
Судя по всему, вы пытаетесь решить другую проблему, чем указано в вашем примере. Насколько я понимаю из ваших комментариев, вы пытаетесь создать клон фактического типа данных, хранящегося указателем в векторе. Иногда его называют «виртуальным конструктором». Для этого вам нужно создать функцию virtual clone() в классах, которые вы хотите клонировать, обычно возвращая новый объект, созданный путем копирования.
@MateuszBiernat «Eq[x][y] это именно то, что я пытаюсь использовать в decltype» — не соответствует названию вашего вопроса. Не согласно тексту вашего вопроса (за исключением кода). Следующий человек, задавший тот же вопрос, не должен предполагать, что заголовок неправильный, и копаться в вашем коде, чтобы выяснить, тот же ли это вопрос, что и у него.





decltype разрешается компилятором во время компиляции.
Он не учитывает (и не может) учитывать, ссылается ли указатель на базовый класс на экземпляр производного класса во время выполнения.
В твоем случае:
holder и temp оба относятся к типу item*, поэтому компилятор разрешит эти два использования decltype в вашем вопросе как item*. После применения std::remove_pointer они станут item (и вы сможете new их).
Что касается Eq[x][y] — на самом деле это если ввести item*& (ссылка на item*) и останется прежним после применения std::remove_pointer. Поскольку вы не можете использовать new со ссылочным типом, вы получите ошибку компиляции.
MSVC, например, выдает следующую ошибку:
error C2464: '_Ty': cannot use 'new' to allocate a reference
with
[
_Ty=item *&
]
Что касается вывода типа во время выполнения (о нем спрашивают в комментариях):
C++ не поддерживает полное отражение, поэтому вы не можете проверить тип объекта во время выполнения и использовать этот тип как есть для создания нового экземпляра.
Вам нужно будет реализовать некоторый код, чтобы выполнить эту тяжелую работу, например. какая-то фабрика.
Вы можете начать с этого поста: Можно ли создать экземпляр объекта по его типу в C++?.
Спасибо чувак! Как мне тогда получить тип во время выполнения?
Добавил некоторую информацию об этом.
Думаю, от твоего друга достаточно информации :) Большое тебе спасибо. Я проверю это
Хотя ваша основная мысль верна (отражение во время компиляции для наследования во время выполнения невозможно, поэтому с этим подходом не будет клонирования типов элементов), в вашем ответе есть ошибка, и это также как бы отвечает на вопрос, заданный изначально. Eq[x][y] не относится к типу item*; это типа item*&. std::remove_pointer_t<decltype(Eq[x][y])> по-прежнему будет item*&, а new такого типа не будет работать (это касается «варианта 1 против варианта 2» в вопросе, почему помогает временно).
@АндрейТуркин, ты прав. Я обновил свой ответ.
Я использовал заводской шаблон, который здесь отлично работает.
@Mateusz, приятно слышать.
decltype разрешается при компиляции. Думаю, это ответ на вопрос. Как мне получить тип класса во время выполнения?