By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,897 Members | 1,608 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,897 IT Pros & Developers. It's quick & easy.

Can I dynamically create vectors of multiple depths?

P: n/a
Rob
This actually compiles and works but it doesn't seem like the best
code, so I was wondering is there another way to do this?

Expand|Select|Wrap|Line Numbers
  1. template <typename Tvector<T>* addDepth(T)
  2. {
  3. return new vector<T>;
  4. }
  5.  
  6. ....a templated meth...
  7. {
  8. //Create multi-depth vector based on length
  9. void* vec;
  10. int length = getLength( obj );
  11. for ( int i = 0; i < length; i++ )
  12. {
  13. vec = addDepth( someValue );
  14. }
  15.  
  16. vector<T2>* b = ( vector<T2>* ) vec;
  17. }
  18.  
  19.  
Jun 27 '08 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Rob
On Apr 13, 11:04*pm, Rob <someidunknown1...@yahoo.comwrote:
This actually compiles and works but it doesn't seem like the best
code, so I was wondering is there another way to do this?

Expand|Select|Wrap|Line Numbers
  1. template <typename Tvector<T>* addDepth(T)
  2. {
  3. * * *return new vector<T>;
  4. }
  5. ...a templated meth...
  6. {
  7. * * *//Create multi-depth vector based on length
  8. * * *void* vec;
  9. * * *int length = getLength( obj );
  10. * * *for ( int i = 0; i < length; i++ )
  11. * * *{
  12. * * * * * *vec = addDepth( someValue );
  13. * * *}
  14. * * *vector<T2>* b = ( vector<T2>* ) vec;
  15. }
  16.  
Whoops. I meant:

for ( int i = 0; i < length; i++ )
{
if ( i == 0 ) vec = addDepth( someValue );
else vec = addDepth( vec );
}
Jun 27 '08 #2

P: n/a
Rob wrote:
On Apr 13, 11:04*pm, Rob <someidunknown1...@yahoo.comwrote:
>This actually compiles and works but it doesn't seem like the best
code, so I was wondering is there another way to do this?

Expand|Select|Wrap|Line Numbers
  1. template <typename Tvector<T>* addDepth(T)
  2. {
  3. return new vector<T>;
  4. }
  5. ...a templated meth...
  6. {
  7. //Create multi-depth vector based on length
  8. void* vec;
  9. int length = getLength( obj );
  10. for ( int i = 0; i < length; i++ )
  11. {
  12. vec = addDepth( someValue );
  13. }
  14. vector<T2>* b = ( vector<T2>* ) vec;
  15. }

Whoops. I meant:

for ( int i = 0; i < length; i++ )
{
if ( i == 0 ) vec = addDepth( someValue );
else vec = addDepth( vec );
}
What is the problem you want to solve? The code above has undefined behavior
in the casting and looses handles to allocated memory, which therefore
leaks. It is impossible to tell how to better solve your problem since the
problem cannot be deduced from the proposed solution.
Best

Kai-Uwe Bux
Jun 27 '08 #3

P: n/a
* Rob:
On Apr 13, 11:04 pm, Rob <someidunknown1...@yahoo.comwrote:
>This actually compiles and works but it doesn't seem like the best
code, so I was wondering is there another way to do this?

Expand|Select|Wrap|Line Numbers
  1. template <typename Tvector<T>* addDepth(T)
  2. {
  3.      return new vector<T>;
  4. }
  5. ...a templated meth...
  6. {
  7.      //Create multi-depth vector based on length
  8.      void* vec;
  9.      int length = getLength( obj );
  10.      for ( int i = 0; i < length; i++ )
  11.      {
  12.            vec = addDepth( someValue );
  13.      }
  14.      vector<T2>* b = ( vector<T2>* ) vec;
  15. }

Whoops. I meant:

for ( int i = 0; i < length; i++ )
{
if ( i == 0 ) vec = addDepth( someValue );
else vec = addDepth( vec );
}
What do you mean by "works": what is the external effect that you have observed
and that you're pleased with?
- Alf
Jun 27 '08 #4

P: n/a
Rob
On Apr 14, 12:01*am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Rob wrote:
On Apr 13, 11:04*pm, Rob <someidunknown1...@yahoo.comwrote:
This actually compiles and works but it doesn't seem like the best
code, so I was wondering is there another way to do this?
Expand|Select|Wrap|Line Numbers
  1. template <typename Tvector<T>* addDepth(T)
  2. {
  3. return new vector<T>;
Expand|Select|Wrap|Line Numbers
  1.         
  2.                         
  3.                 }
  •  
  •         
  •                         
  •                 ...a templated meth...
  • {
  • //Create multi-depth vector based on length
  • void* vec;
  • int length = getLength( obj );
  • for ( int i = 0; i < length; i++ )
  • {
  • vec = addDepth( someValue );
  • }
  •  
  •         
  •                         
  •                 vector<T2>* b = ( vector<T2>* ) vec;
  •  
  •         
  •                         
  •                 }
  •  
  •         
  •                         
  •  
  •  
  •  
  • Whoops. I meant:
    * * *for ( int i = 0; i < length; i++ )
    * * *{
    * * * * * *if ( i == 0 ) vec = addDepth( someValue );
    * * * * * *else vec = addDepth( vec );
    * * *}

    What is the problem you want to solve? The code above has undefined behavior
    in the casting and looses handles to allocated memory, which therefore
    leaks. It is impossible to tell how to better solve your problem since the
    problem cannot be deduced from the proposed solution.

    Best

    Kai-Uwe Bux I want to be able to dynamically (at runtime) create a vector of
    compile-time-unknown type. And the vector might be a vector of an int,
    or a string or a vector of a vector of a string, etc. How would I do
    that?
    Jun 27 '08 #5

    P: n/a
    Rob wrote:
    >
    I want to be able to dynamically (at runtime) create a vector of
    compile-time-unknown type. And the vector might be a vector of an int,
    or a string or a vector of a vector of a string, etc. How would I do
    that?
    You can't.

    std::vector is a template, you can only instantiate a template at
    compile time.

    The best you can do is use a the factory pattern to return vectors of
    known types.

    --
    Ian Collins.
    Jun 27 '08 #6

    P: n/a
    Rob <so***************@yahoo.comwrites:
    On Apr 14, 12:01*am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
    >Rob wrote:
    On Apr 13, 11:04*pm, Rob <someidunknown1...@yahoo.comwrote:
    This actually compiles and works but it doesn't seem like the best
    code, so I was wondering is there another way to do this?
    >
    Expand|Select|Wrap|Line Numbers
    1. template <typename Tvector<T>* addDepth(T)
    2. {
    3. return new vector<T>;
    Expand|Select|Wrap|Line Numbers
    1.         
    2.                 >}
  •  
  •         
  •                 >...a templated meth...
  • {
  • //Create multi-depth vector based on length
  • void* vec;
  • int length = getLength( obj );
  • for ( int i = 0; i < length; i++ )
  • {
  • vec = addDepth( someValue );
  • }
  •  
  •         
  •                 >vector<T2>* b = ( vector<T2>* ) vec;
  •  
  •         
  •                 >}
  •  
  •         
  •                 >
  •  
  •  
  • Whoops. I meant:
    * * *for ( int i = 0; i < length; i++ )
    * * *{
    * * * * * *if ( i == 0 ) vec = addDepth( someValue );
    * * * * * *else vec = addDepth( vec );
    * * *}

    What is the problem you want to solve? The code above has undefined behavior
    in the casting and looses handles to allocated memory, which therefore
    leaks. It is impossible to tell how to better solve your problem since the
    problem cannot be deduced from the proposed solution.

    Best

    Kai-Uwe Bux
    I want to be able to dynamically (at runtime) create a vector of
    compile-time-unknown type. And the vector might be a vector of an int,
    or a string or a vector of a vector of a string, etc. How would I do
    that? You are wanting typed _values_, like in Lisp. You would do that by
    applying Greenspun's Tenth Law.

    Specifically, you would do:

    #include <vector>
    #include <iostream>
    #include <string>
    #include <iterator>
    #include <fstream>

    typedef enum { ttSymbol, ttCharacter, ttByte, ttInteger, ttString, ttVector } TypeTag;

    class Object {
    public:
    virtual TypeTag getTypeTag(void)=0;
    virtual void print(std::ostream& out)=0;
    };

    class Symbol:public Object {
    private:
    std::string name;
    public:
    virtual TypeTag getTypeTag(void){return ttSymbol;}
    Symbol(std::string aName):name(aName){};
    inline std::string getName(void){return name;}
    virtual void print(std::ostream& out){out<<name;};
    };

    static Symbol* NIL=new Symbol("NIL");

    class Character:public Object {
    private:
    char value;
    public:
    virtual TypeTag getTypeTag(void){return ttCharacter;};
    Character(char aValue):value(aValue){};
    inline char getChar(void){return value;};
    virtual void print(std::ostream& out){ out.put(value); };
    };

    class Byte:public Object {
    private:
    char value;
    public:
    virtual TypeTag getTypeTag(void){return ttByte;};
    Byte(char aValue):value(aValue){};
    inline char getByte(void){return value;};
    virtual void print(std::ostream& out){ out<<int(value); };
    };

    class Integer:public Object {
    private:
    int value;
    public:
    virtual TypeTag getTypeTag(void){return ttInteger;};
    Integer(int aValue):value(aValue){};
    inline int getInt(void){return value;};
    virtual void print(std::ostream& out){ out<<value; };
    };

    class String:public Object {
    private:
    std::string value;
    public:
    virtual TypeTag getTypeTag(void){return ttString;};
    String(std::string aValue):value(aValue){};
    inline std::string& getString(void){return value;};
    virtual void print(std::ostream& out){ out<<"\""<<value/*todo: escape " and \ in value*/<<"\""; };
    };

    class Vector:public Object {
    private:
    std::vector<Object*value;
    public:
    virtual TypeTag getTypeTag(void){return ttVector;};
    Vector(int size=0,Object* initialElement=NIL):value(std::vector<Object*>(siz e,initialElement)){};
    inline std::vector<Object*>& getVector(void){return value;};
    virtual void print(std::ostream& out);
    };

    void Vector::print(std::ostream& out){
    out<<"#(";
    typedef std::vector<Object*>::iterator Iter;
    Iter end=value.end();
    for(Iter cur=value.begin();cur!=end;cur++){
    if(cur!=value.begin()){
    out<<" ";
    }
    (*cur)->print(out);
    }
    out<<")";
    }

    // Really, multidimentional arrays are another beast (ie class
    // Array:public Object{ etc } than vectors, but here is how you can
    // implement them with vectors of vectors, as you asked for this
    // kind.

    Vector* makeArray(std::vector<intdimensions,Object* initialValue){
    if(dimensions.size()==0){
    return NULL;
    }
    int firstDim=dimensions[0];
    dimensions.erase(dimensions.begin());
    Vector* result=new Vector();
    if(dimensions.size()==0){
    for(int i=0;i<firstDim;i++){
    result->getVector().push_back(initialValue);
    }
    }else{
    for(int i=0;i<firstDim;i++){
    result->getVector().push_back(makeArray(dimensions,initia lValue));
    }
    }
    return(result);
    }

    int main(void){
    Vector* v=new Vector(1);
    v->getVector().push_back(new Character('A'));
    v->getVector().push_back(new Byte(65));
    v->getVector().push_back(new Integer(42));
    v->getVector().push_back(new String("Hello"));
    int dims[] = {2,3,4};
    std::vector<intvdims(dims,dims+sizeof(dims)/sizeof(dims[0]));
    Vector* u=makeArray(vdims,new Integer(0));
    v->getVector().push_back(u);

    v->print(std::cout);
    std::cout<<std::endl;
    return(0);
    }
    /*
    -*- mode: compilation; default-directory: "~/src/tests-c++/" -*-
    Compilation started at Mon Apr 14 10:52:06

    p=type-tag ; g++ -o $p $p.c++ && ./$p
    #(NIL A 65 42 "Hello" #(#(#(0 0 0 0) #(0 0 0 0) #(0 0 0 0)) #(#(0 0 0 0) #(0 0 0 0) #(0 0 0 0))))

    Compilation finished at Mon Apr 14 10:52:07
    */

    --
    __Pascal Bourguignon__
    Jun 27 '08 #7

    P: n/a
    pj*@informatimago.com (Pascal J. Bourguignon) writes:
    >
    You are wanting typed _values_, like in Lisp. You would do that by
    applying Greenspun's Tenth Law.
    "Greenspun's Tenth Rule of Programming: any sufficiently complicated C
    or Fortran program contains an ad hoc informally-specified bug-ridden
    slow implementation of half of Common Lisp."

    - Philip Greenspun

    "Including Common Lisp."

    - Robert Morris

    Nice example, though. You are doing your very best to convince all
    these C++ programmers to try Lisp. You should explain the
    correspondence between "functors" and the way Lambda works in a
    lexically scoped Lisp, for example Scheme.

    Chip

    --
    Charles M. "Chip" Coldwell
    "Turn on, log in, tune out"
    GPG Key ID: 852E052F
    GPG Key Fingerprint: 77E5 2B51 4907 F08A 7E92 DE80 AFA9 9A8F 852E 052F
    Jun 27 '08 #8

    This discussion thread is closed

    Replies have been disabled for this discussion.