Хранение типа в C++

Действительно ли возможно сохранить имя типа как переменную C++? Например, как это:

type my_type = int; // or string, or Foo, or any other type
void* data = ...;
my_type* a = (my_type*) data;

Я знаю, что 99,9% времени там является лучшим способом сделать то, что Вы хотите, не обращаясь к кастингу пустых указателей, но мне любопытно, если C++ позволяет этот вид вещи.

29
задан perimosocordiae 1 April 2010 в 17:04
поделиться

7 ответов

Нет, в C ++ это невозможно.

Оператор RTTI typeid позволяет вам получить некоторую информацию о типах во время выполнения: вы можете получить имя типа и проверить, совпадает ли он с другим типом, но не более того.

24
ответ дан 28 November 2019 в 01:18
поделиться

Лучше иметь общий базовый класс, содержащий метод загрузки и интерфейс для загрузчиков . Это позволило бы другим частям программы загружать данные в общем случае, не зная о классе-потомке:

struct Load_Interface;

struct Loader
{
  virtual void visit(Load_Interface&) = 0;
}

struct Load_Interface
{
  virtual void accept_loader(Loader& l)
    {
        l.visit(*this);
    }
};

Этот дизайн позволяет избежать необходимости знать типы объектов.

1
ответ дан 28 November 2019 в 01:18
поделиться

Вы не можете сделать это в C ++, но вы можете использовать усиление любой библиотеки, а затем проверить ее тип. Пример:

bool is_int(const boost::any & operand)
{
  return operand.type() == typeid(int);
}

http://www.boost.org/doc/libs/1_42_0/doc/html/any/s02.html

9
ответ дан 28 November 2019 в 01:18
поделиться

Да, если кодировать самостоятельно.

enum Foo_Type{
    AFOO,
    B_AFOO,
    C_AFOO,
    RUN
};

struct MyFoo{
    Foo_Type m_type;
    Boost::shared_ptr<Foo> m_foo;
}

как прокомментировано ниже, я не учел, что все эти типы "foo" должны быть связаны с Foo. По сути, Foo будет вашим интерфейсом.

3
ответ дан 28 November 2019 в 01:18
поделиться

Не так, как написано, но вы могли бы сделать что-то подобное ...

class Type
{
    public:
        virtual ~Type(){}
        virtual void* allocate()const=0;
        virtual void* cast(void* obj)const=0;
};

template<typename T> class TypeImpl : public Type
{
      public:
         virtual void* allocate()const{ return new T; }
         virtual void* cast(void* obj)const{ return static_cast<T*>(obj); }
};

// ...
Type* type = new TypeImpl<int>;
void* myint = type->allocate();
// ...

Такие вещи могут быть расширены в зависимости от того, какие функции вам нужны.

16
ответ дан 28 November 2019 в 01:18
поделиться

Нет, вы не можете сохранить тип напрямую, как хотите, но вместо этого вы можете сохранить имя типа.

const char* str = typeid(int).name();

Думаю, всякий раз, когда вы планировали использовать эту переменную для сравнения, вы могли бы вместо этого сравнить переменную str с name () типов.

const char* myType = typeid(int).name();

//....

//Some time later:
if(!strcmp(myType, typeid(int).name()))
{
  //Do something
}

Дополнительная информация доступна здесь

6
ответ дан 28 November 2019 в 01:18
поделиться

Типы не являются объектами в C ++ (например, в Ruby), поэтому вы не можете хранить экземпляры типа. На самом деле типы никогда не появляются в исполняемом коде (RTTI - это просто дополнительное хранилище).

Судя по вашему примеру, похоже, вы ищете typedef.

typedef int Number;
Number one = 1;
Number* best = (Number*) one;

Обратите внимание, что typedef не хранит тип; это псевдоним типа.

1
ответ дан 28 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

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