Указатель на 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;
};

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

Другие вопросы по тегам