В чем разница между decltype(type) и decltype(vector_of_type)?

У меня проблема с 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?

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

Как я могу этого добиться?

decltype разрешается при компиляции. Думаю, это ответ на вопрос. Как мне получить тип класса во время выполнения?

Mateusz 08.06.2024 18:07

«Вектор Eq того же типа, что и holder и itemGrabbed». -- Нет. Элементы элементов Eq имеют тот же тип, что и две другие переменные, но вектор X не того же типа, что и X. Вы намеревались ссылаться на элементы вместо вектора? Это лучше соответствовало бы вашему коду.

JaMiT 08.06.2024 18:15

«Интересно, возможно ли это сделать» — Что именно «это»? Вы описали свою настройку и показали некоторый код, но не указали, какова ваша цель. Почему вы используете decltype? Как вы думаете, что вы получите от такого многословия?

JaMiT 08.06.2024 18:18
Eq[x][y] это именно то, что я пытаюсь использовать в decltype, проблема в том, что decltype мне не подходит
Mateusz 08.06.2024 18:19
item имеет другую функцию update(), чем itemAxe. Следующий шаг — *this->itemGrabbed = *Eq[x][y];, а позже я назначаю это где-то еще, поэтому мне нужно, чтобы это был точный указатель класса, у меня есть копия и оператор = готов.
Mateusz 08.06.2024 18:25

Судя по всему, вы пытаетесь решить другую проблему, чем указано в вашем примере. Насколько я понимаю из ваших комментариев, вы пытаетесь создать клон фактического типа данных, хранящегося указателем в векторе. Иногда его называют «виртуальным конструктором». Для этого вам нужно создать функцию virtual clone() в классах, которые вы хотите клонировать, обычно возвращая новый объект, созданный путем копирования.

Gene 08.06.2024 19:45

@MateuszBiernat «Eq[x][y] это именно то, что я пытаюсь использовать в decltype» — не соответствует названию вашего вопроса. Не согласно тексту вашего вопроса (за исключением кода). Следующий человек, задавший тот же вопрос, не должен предполагать, что заголовок неправильный, и копаться в вашем коде, чтобы выяснить, тот же ли это вопрос, что и у него.

JaMiT 09.06.2024 01:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
106
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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++?.

Спасибо чувак! Как мне тогда получить тип во время выполнения?

Mateusz 08.06.2024 18:16

Добавил некоторую информацию об этом.

wohlstad 08.06.2024 18:18

Думаю, от твоего друга достаточно информации :) Большое тебе спасибо. Я проверю это

Mateusz 08.06.2024 18:28

Хотя ваша основная мысль верна (отражение во время компиляции для наследования во время выполнения невозможно, поэтому с этим подходом не будет клонирования типов элементов), в вашем ответе есть ошибка, и это также как бы отвечает на вопрос, заданный изначально. Eq[x][y] не относится к типу item*; это типа item*&. std::remove_pointer_t<decltype(Eq[x][y])> по-прежнему будет item*&, а new такого типа не будет работать (это касается «варианта 1 против варианта 2» в вопросе, почему помогает временно).

Andrey Turkin 08.06.2024 18:33

@АндрейТуркин, ты прав. Я обновил свой ответ.

wohlstad 08.06.2024 19:05

Я использовал заводской шаблон, который здесь отлично работает.

Mateusz 11.06.2024 08:32

@Mateusz, приятно слышать.

wohlstad 11.06.2024 10:24

Другие вопросы по теме

Похожие вопросы

Перемещение после копирования при присвоении результата условного оператора
Почему `std::integral_constant` имеет `::type`, который ссылается на себя?
Агрегатная инициализация, которая имеет инициализатор члена, когда значения инициализации меньше количества членов
Макросы LITTLE_ENDIAN, BIG_ENDIAN и BYTE_ORDER должны загрязнять мое глобальное пространство имен с помощью GCC?
Что происходит, когда сопрограмма возвращается в приостановленную сопрограмму?
Boost Asio: исполнители в сопрограммах C++20
Можно ли рассматривать reinterpret_cast как небезопасный обходной путь, когда динамический_cast недоступен?
Как предотвратить возникновение противоречивых ошибок в конфигурациях отладки и выпуска для «недоступного кода» и «не все пути возвращают значение»
Можно ли в Visual Studio Code автоматически переключаться на панель «Проблемы», когда при сборке возникают ошибки?
Как сборка этой функции реализует условие?