views:

63

answers:

3

Hi!

let's say i want to have a member variable for a pointer to std::vector but i do not want to specify what type of variable it stores. I want to access only those functions that are independant of it's actual generic type. is this possible with c++? something like this:

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();
}

note: i do not want to template Foo and i want to use only a single instance of Foo with vectors of different type.

of course - if I could alter the class vector then i could create an untemplated baseclass

class Ivector{
    virtual int size()=0;
};

and then make the

class vector<T> : public IVector...

inherit from Ivector. but what do I do if i can't alter the class in question and the templated class does not have such an untemplated baseclass?

thanks!

A: 

The line

std::vector* myVec

is not syntactically correct. One has to specify the type of the vector elements.

You may want to do something on the line of

template< typename T >
class Foo{
  private:
    std::vector<T> * myVec;
};

However, even that doesn't look nice, re-evaluating the design might be more important here.

ArunSaha
yes i know that. but the point is that I wouldn't want to templatize Foo. I could store the pointer instead as void* - but then i had no chance to call .size() even though i knew it's a pointer to a vector (but i wouldn't know a pointer to a vector of what type)
Mat
+1  A: 

You could do this:

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;
};

And so on, but I doubt this is too useful in any real situation.

GMan
hey that's actually quite neat! didn't think of capsulating it. it however still poses the effort of creating a special class for it. but it's a working workarround - thx :)
Mat
@Mat: Work around *for what*?
GMan
Mat
@Mat: So there is a problem you'd like to solve...
GMan
+3  A: 

You are almost at the answer. Instead of making std::vector inherit from Ivector, create a new class:

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
};

Now have your Foo class keep a pointer to Ivector instead of 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;
}
Daniel Feryance