может ли c сохранить это? шаблон (сохраните имя_типа T, чтобы я мог использовать его позже?)

#c

#c

Вопрос:

 #include <iostream>

template <typename T>
class Item {
public:
  T item;
  void* ptr = nullptr;
  Item(T var): item(var) {}

  unknown next(){
    if ((unknown*)ptr != nullptr){
      std::cout<<"It is not a null pointer!"<<std::endl;
      return (unkown*)ptr
    }else{
      std::cout<<"It is a null pointer..."<<std::endl;
      return NULL
    }
  }

  template <typename temp>
  void pass(temp *var){
    ptr = var;
  }
};

int main() { 
  Item<int> i(100);
  Item<float> n(200.0);
  i.pass(amp;n);
  i.next();
}
  

Моя проблема в том, чтобы «запомнить» тип T , чтобы я мог заменить unknown .

Мне нужен void* указатель, указывающий на неизвестный тип, и мне нужно ввести приведение к нужному типу, чтобы получить то, что я в нем сохранил. При Item создании ничего не было зарегистрировано (ничего не должно быть зарегистрировано).

Если вы, ребята, каким-то образом знаете, как это сделать, возможно ли также изменить тип «запоминается» во время компиляции?

Комментарии:

1. Я предполагаю, что вы хотите заменить unknown на temp , а не на T ? Это невозможно.

2. Что мешает вам использовать T во всех местах unknown ? После исправления нескольких ошибок (пропущенных ; и * ) ваш код затем компилируется и выводит «Это не нулевой указатель!». Я не вижу вашей проблемы, если вы не пытаетесь использовать T извне класса. И даже тогда есть очевидное решение.

3. В void * коде C следует использовать только для взаимодействия с API библиотеки C. Никогда не нужно использовать void * в хорошо разработанном коде C для чего-либо.

Ответ №1:

pass поскольку шаблон может принимать бесконечное количество типов, в то время как возвращаемый тип next фиксирован к одному типу. Вы запрашиваете способ обработки всех типов как одного типа, и, к сожалению void* , это единственный способ; вы не можете восстановить тип, используемый pass в.

Я не уверен на 100% во всех ваших вариантах использования этого класса, поэтому я опишу несколько методов удаления типов, которые вам следует изучить:

  • Рассмотрите возможность использования a std::variant и возложите ответственность за то, что делать с содержащимся типом, на посетителя, определенного пользователем. например, Item<int, double> хранит a variant<int, double>

  • В качестве альтернативы, используйте a std::any и возложите бремя восстановления информации о типе на вызывающего.

  • В качестве альтернативы можно принудительно удалить тип с помощью полиморфизма; вместо void* этого собственный указатель на базовый класс.

  • Другим подходом к стиранию типов является подход Sean Parent «полиморфизм во время выполнения«, в котором пользователь предоставляет реализацию требуемого поведения в виде функции, которую можно обнаружить с помощью поиска, зависящего от аргумента. С помощью полиморфизма только для внутреннего использования вы можете вызвать соответствующую функцию для содержащегося указателя (не слишком отличающуюся от того, как std::function это реализовано).