Re: Can I dynamically create vectors of multiple depths?
Rob <someidunknown1234@yahoo.com> writes:
On Apr 14, 12:01?am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
Rob wrote:
On Apr 13, 11:04?pm, Rob <someidunknown1...@yahoo.com> wrote:
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?
[CODE]
template <typename T> vector<T>* addDepth(T)
{
return new vector<T>;
}
...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;
}
[/CODE]
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*>(size,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<int> dimensions,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,initialValue));
}
}
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<int> vdims(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__