Может ли тип переменной быть объектом в C ++? - PullRequest
0 голосов
/ 02 августа 2020

Надеюсь, мой вопрос ясен. Я хотел бы сделать что-то вроде этого:

TYPE tipo = int;
tipo = float;

Чтобы позже иметь возможность делать другие подобные вещи:

void* ptr = new tipo();
cout << *(tipo*)ptr;

Это, в основном, для определения типа пустоты. указатель (или variant -объект, или any -объект) и его отсылка, но во время выполнения.

Это вся моя проблема: я пытаюсь создать массив любой тип переменной (имитирующий ОЗУ P C для компилятора). Для этого я использую указатели void и другой массив, в котором я храню целое число, представляющее тип элемента, хранящегося в первом массиве. Итак, я могу правильно отлить элемент, когда это потребуется. Этот код работает, но, конечно, он не так функциональн, потому что мне пришлось бы использовать все переключатели каждый раз, когда мне нужно было восстанавливать элемент из моего массива:

#define INT     0
#define FLOAT   1
#define BOOL    2

int main(void)
{
    void* ram[] = { new float(2.5), new float(5.8), new bool(true), new int(8) };
    int tipo[]  = { FLOAT,          FLOAT,          BOOL,           INT       };

    int i = 1;
    int salida;

    switch (i)
    {
        case INT:   salida = *(int*)ram[i];     break;
        case FLOAT: salida = *(float*)ram[i];   break;
        case BOOL:  salida = *(bool*)ram[i];    break;
    }

    cout << salida;

    return 86;
}

Интересно, есть ли у меня "массив типов", поэтому я могу сделать что-то вроде этого

int main(void)
{
    void* ram[] = { new float(2.5), new float(5.8), new bool(true), new int(8) };
    TYPE tipo[] = { float,          float,          bool,           int       };

    int i = 1;
    int salida = *(tipo[i]*)ram[i];

    cout << salida;

    return 86;
}

Возможно ли это? Если нет, как бы вы решили эту проблему?

Ответы [ 2 ]

4 голосов
/ 02 августа 2020

Ваш первый блок кода в основном в порядке, но не очень хорош для производительности, потому что с каждым выделением new связаны накладные расходы, и вы платите эту цену за каждый отдельный элемент данных.

Второй блок кода на самом деле нежизнеспособен, по крайней мере, не так, как вы предлагаете.

Есть лучшее решение: вектор вариантов. В вашем случае:

std::vector<std::variant<int, float, bool>> values;

Здесь вы можете сохранить все три типа, например:

values.emplace_back(2.5f);
values.emplace_back(5.8f);
values.emplace_back(true);
values.emplace_back(8);

Размер этого контейнера можно изменять, он содержит все ваши данные в одном большом распределении (которое для небольших типов значительно сокращает накладные расходы на выделение памяти) и может быть расширен для поддержки большего количества типов без дополнительной работы.

Ссылка: https://en.cppreference.com/w/cpp/utility/variant

2 голосов
/ 02 августа 2020

Хотя ответ Джона, безусловно, является хорошим предложением о том, как вы должны подойти к своей проблеме, чтобы строго ответить на вопрос заголовка, существует класс std :: type_info , который хранит информацию о типе. Это позволяет, например, сравнивать типы или печатать их имена.

Вы можете использовать typeid () , чтобы получить его:

#include <typeinfo>
#include <iostream>

int main()
{
  const std::type_info& info = typeid(float);
  std::cout << info.name() << std::endl;
  return 0;
}
...