#c #mapping #stdvector
#c #отображение #stdvector
Вопрос:
Предполагая, что я хочу иметь несколько векторов, каждый из которых содержит объекты разного типа, есть ли какой-либо способ сопоставить указатели с ними? Что-то вроде этого:
std::vector<class1> vec1;
std::vector<class2> vec2;
std::vector<class3> vec3;
mapper.addVectorPtr(amp;vec1);
mapper.addVectorPtr(amp;vec2);
mapper.addVectorPtr(amp;vec3);
std::vector<class1> * ptr1 = mapper.getVectorPtr<class1>;
std::vector<class2> * ptr2 = mapper.getVectorPtr<class2>;
std::vector<class3> * ptr3 = mapper.getVectorPtr<class3>;
Вероятно, я мог бы использовать пользовательский класс с векторным указателем в качестве члена, который был бы производным от общего базового класса. Затем я мог бы перенести их в нужный класс и получить указатель, но я хотел бы посмотреть, есть ли какие-то лучшие варианты.
Комментарии:
1. Знаете ли вы class1 … class N во время компиляции? Или вы ищете полностью универсальное решение?
2. @quantdev Не могли бы вы немного уточнить? Это должно работать для любого класса, если вы это имеете в виду.
Ответ №1:
Вы должны проверить http://www.cplusplus.com/reference/typeinfo/type_info / . Вы можете получить typeinfo таким образом. Позволяет создавать карту с целым числом (= хэш-кодом) в качестве ключа.
затем вы можете реализовать свой mapclass следующим образом (требуется конструктор без аргументов)
#include <vector>
#include <typeinfo>
#include <map>
#include <iostream>
class typemap{
std::map<unsigned long, void*> m_ptrs;
public:
template<typename A>
void addVectorPtr(std::vector<A>* b){
A a;
m_ptrs[ typeid(a).hash_code() ] = b;
}
template<typename A>
std::vector<A>* getVectorPtr(){
A a;//this is why you need the default constructor
return (std::vector<A>*) (m_ptrs[ typeid(a).hash_code() ]);
}
};
int main(){
std::vector<int>* t1 = new std::vector<int>(3,3);
typemap tm;
tm.addVectorPtr(t1);
std::vector<int> v=*(tm.getVectorPtr<int>());
for(auto it = v.begin(); it!= v.end(); it){
std::cout<<*it<<std::endl;
}
}
Комментарии:
1. Я думаю, это то, что я ищу. Я бы использовал type_index для сопоставления, но по какой-то причине приведение из void * мне вообще не приходило в голову!
2. @Veritas Я на самом деле пытаюсь заставить его работать здесь, но, похоже, у меня это не получается. В этом примере, безусловно, много ошибок
3. Может быть, я не проверял. Это подход, который мне нравится.
4. Мне было интересно, что, если мы заменим addVectorPtr шаблонной функцией addVector, которая создаст вектор и сохранит его внутри в mapper? getVectorPtr будет заменен шаблонной функцией getVector, которая вернет ссылку на требуемый вектор. Должен ли я следовать своему первоначальному решению и создавать пользовательский базовый класс и производный класс с помощью std::vector в качестве его члена, а затем приводить по мере необходимости и впоследствии извлекать вектор, или есть лучшее решение?
5. Если я правильно понимаю, все стало бы намного сложнее. Реализация того, что вы хотите, проста: просто определите addVector() так, чтобы он вызывал «addVectorPtr(new std::vector<type>);» и реализуйте addVector следующим образом: » return getVectorPtr() «. Реальная трудность заключалась бы в написании деструктора, я пока не вижукак бы вы это сделали, не имея базового типа, поскольку вы не можете удалить указатель void.