Указатель на std::vector произвольного типа (или любой другой шаблонный класс)
Скажем, я хочу иметь переменную-член для указателя на std::vector, но я не хочу указывать, какой тип переменной он хранит. Я хочу получить доступ только к тем функциям, которые не зависят от его фактического универсального типа. это возможно с C++? что-то вроде этого:
class Foo{
public:
void setVec(std::vector* someVec){
myVec = someVec;
};
int getSize(){
return myVec.size();
};
private:
std::vector* myVec;
};
int main(){
Foo foo;
vector<int> vec1;
vector<float> vec2;
foo.setVec(&vec1);
cout<<foo.getSize();
foo.setVec(&vec2);
cout<<foo.getSize();
}
примечание: я не хочу шаблонировать Foo и хочу использовать только один экземпляр Foo с векторами другого типа.
конечно - если бы я мог изменить вектор класса, то я мог бы создать базовый класс без шаблонов
class Ivector{
virtual int size()=0;
};
а затем сделать
class vector<T> : public IVector...
наследовать от Ivector. но что мне делать, если я не могу изменить рассматриваемый класс, а шаблонный класс не имеет такого необработанного базового класса?
Спасибо!
3 ответа
Вы почти в ответе. Вместо того чтобы заставлять std::vector наследовать от Ivector, создайте новый класс:
template <typename T>
class IVectorImpl : public Ivector
{
public:
explicit IVectorImpl(std::vector<T> * Data) : m_Data(Data){}
std::vector<T> * m_Data;
...
virtual int size() const {return m_Data->size();}
// Implement all the Ivector functions here to call the respective functions off of m_Data
};
Теперь ваш класс Foo хранит указатель на Ivector вместо std::vector.
Make Foo:: setVec templated
template <typename T>
void setVec(std::vector<T> * vec)
{
Ivector * newVec = new IVectorImpl<T>(vec);
delete myVec;
myVec = newVec;
}
Вы могли бы сделать это:
class vector_container_base
{
public:
~vector_container_base() {}
virtual std::size_t size() const = 0;
};
template <typename T>
class vector_container :
public vector_container_base
{
public:
typedef std::vector<T> vector_type;
std::size_t size() const
{
return mVector.size();
}
private:
vector_type mVector;
};
И так далее, но я сомневаюсь, что это слишком полезно в любой реальной ситуации.
Линия
std::vector* myVec
не является синтаксически правильным. Нужно указать тип векторных элементов.
Вы можете сделать что-то на линии
template< typename T >
class Foo{
private:
std::vector<T> * myVec;
};
Однако, даже если это не выглядит хорошо, переоценка дизайна может быть более важной здесь.