Re: container of pointers to vectors of different types

Discussion in 'C++' started by Victor Bazarov, Jul 31, 2003.

  1. "Sean Dettrick" <> wrote...
    > I would like to make a container of pointers, where
    > each pointer points at a data vector of arbitrary type.
    > I then wish to access the data vector member functions
    > via the [] operator and the pointer vector elements, e.g.:
    >
    > Container_of_pointers entries;
    > entries.resize(3);
    > entries[0] = &x; // x is a vector<int>
    > entries[1] = &y; // y is a vector<float>
    > entries[2] = &z; // z is a vector<double>
    >
    > // resize x, y, and z via the pointers:
    > for ( int entry=0; entry<3; entry++ ) entries[entry]->resize( 5 );


    You can only do that if the vectors of different types share the
    common base class, which they don't. The solution I see is for
    you to create that artificial connection by introducing the needed
    hierarchy:

    class genericvector
    {
    // all funcitonality you need, declared pure virtual
    };

    template<class T> myvector : public genericvector, private vector<T>
    {
    public:
    // all funcitonality you need, declared virtual (to
    // override the 'genericvector's, but implemented by
    // calling the corresponding members from 'vector<T>'
    };

    int main()
    {
    vector<genericvector*> entries;
    entries.push_back(new myvector<int>);
    entries.push_back(new myvector<double>);
    ...
    }

    Now, the trick would be to design the abstract functionality to
    comply with requirements you need. If you can't do that (and I
    wasn't able to think of something even remotely useful), then
    the only solution for you is a vector<void*>:

    int main()
    {
    vector<void*> entries;
    entries.push_back(new vector<int>);
    entries.push_back(new vector<double>);
    ...
    }

    however, in that case you need some way of distinguishing between
    those vectors when it's time to convert them back (likely using
    'static_cast') into pointers to vectors they were when you pushed
    them into 'entries'.

    BTW, Sean, what is that for? A vector of vectors of arbitrary
    types is basically as useless as Java's Object type...

    Victor
    Victor Bazarov, Jul 31, 2003
    #1
    1. Advertising

  2. "Victor Bazarov" <> wrote in message news:<>...
    > "Sean Dettrick" <> wrote...
    > > I would like to make a container of pointers, where
    > > each pointer points at a data vector of arbitrary type.
    > > I then wish to access the data vector member functions
    > > via the [] operator and the pointer vector elements, e.g.:
    > >
    > > Container_of_pointers entries;
    > > entries.resize(3);
    > > entries[0] = &x; // x is a vector<int>
    > > entries[1] = &y; // y is a vector<float>
    > > entries[2] = &z; // z is a vector<double>
    > >
    > > // resize x, y, and z via the pointers:
    > > for ( int entry=0; entry<3; entry++ ) entries[entry]->resize( 5 );

    >
    > You can only do that if the vectors of different types share the
    > common base class, which they don't. The solution I see is for
    > you to create that artificial connection by introducing the needed
    > hierarchy:
    >
    > snip...


    That might eventually do the trick for me - in my real code I
    have my own container class, ScalarParticle<T> (built on top of vector<T>)
    which I suppose I could instead get to inheret GenericParticle. Maybe in
    the end (after days of agony) it could simplify my class structure
    anyway, since I also have a VectorParticle<T> class which holds several
    ScalarParticle<T> objects, and then an Particles<T> object which holds
    numerous VectorParticle<T> and ScalarParticle<T> objects.

    > snip...
    >
    > however, in that case you need some way of distinguishing between
    > those vectors when it's time to convert them back (likely using
    > 'static_cast') into pointers to vectors they were when you pushed
    > them into 'entries'.


    I confess I have succesfully avoided casting to date, so as to save
    those neurons for other endeavours.

    >
    > BTW, Sean, what is that for? A vector of vectors of arbitrary
    > types is basically as useless as Java's Object type...
    >
    > Victor


    Well, the idea is to simplify the maintenance of my Particles<T> class.
    I have mainly VectorParticle<T> and ScalarParticle<T> objects inside
    the class, but also, horribly, some ScalarParticle<int> objects which
    can't be avoided...
    Each of these objects has its own resize(), print(), read() functions,
    so when I define the resize(), print(), read() methods for the
    Particles<T> class, I have to call the methods for each member.
    I would prefer to do it by looping over a list of members. That way,
    if I later add a member, then I don't have to edit every method:
    just edit a single private method which will be make_member_list().

    Without the ScalarParticle<int> members, this would be straightforward.
    I could easily maintain a list of <int> and a list of <T> members, but
    I thought I might learn some more c++ by maintaining a single list.

    Cheers,
    Sean
    PS here's my Particles<T> def



    template <class T>
    class Particles{
    private:
    Particles( const Particles<T>& rhs ); // copy constructor
    public:
    int npart;
    T qOm; // charge/mass ratio for this species
    T mass,Z;
    T Nions_Npart; // Number of ions represented by each test particle

    // preserved in domain decomposition:
    VectorParticle<T> R;
    VectorParticle<T> V;
    ScalarParticle<T> r; // the radial position

    // not preserved, just resized:
    VectorParticle<T> B;
    VectorParticle<T> E;
    VectorParticle<T> drag1;
    VectorParticle<T> fluidv;
    ScalarParticle<T> drag2;
    ScalarParticle<T> nu_aa;

    ScalarParticle<T> density;
    ScalarParticle<T> Temp;

    ScalarParticle<int> izr0; // OFFENDING MEMBERS
    ScalarParticle<int> izr1;
    ScalarParticle<int> izr2;
    ScalarParticle<int> izr3;

    ScalarParticle<int> iz;
    ScalarParticle<int> ir;
    ScalarParticle<T> w0;
    ScalarParticle<T> w1;
    ScalarParticle<T> w2;
    ScalarParticle<T> w3;

    // NB copy and assignment only copy the particle R and V to save copy operations.
    Particles();
    Particles( int N=0, string name="" );
    ~Particles();
    Particles& operator=(const Particles& rhs);

    int Pack(vector<bool> keep);
    int Discard(const vector<int>& discard, vector<T> Discarded );
    int Discard(const vector<int>& discard, vector<T> Discarded,
    const vector<int>& discard2, vector<T> Discarded2 );
    int Append( const vector<T>& append );
    int Append( const vector<T>& append1,
    const vector<T>& append2 );

    void resize( int n );

    // inquiry functions require both const and non-const versions:
    int size();
    void print( std::eek:stream& output=cout );
    int count_NaNs();

    int size() const;
    void print( std::eek:stream& output=cout ) const;
    int count_NaNs() const;

    };
    Sean Dettrick, Aug 1, 2003
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Xamalek
    Replies:
    7
    Views:
    685
  2. m@j3R ;
    Replies:
    4
    Views:
    410
    Rene Moehring
    Dec 8, 2004
  3. ben
    Replies:
    17
    Views:
    731
    Larry I Smith
    Jun 12, 2005
  4. Replies:
    3
    Views:
    690
    Shadowman
    Mar 26, 2008
  5. Guest
    Replies:
    0
    Views:
    438
    Guest
    Sep 14, 2005
Loading...

Share This Page