Link to home
Start Free TrialLog in
Avatar of Booth882
Booth882

asked on

a variable of type type

is there a variable that holds a type, for instance:

type TypeVar1 = char;
type TypeVar2 = int;

TypeVar1 = TypeVar2;// both int

do you know a way this can be done?  
Avatar of viktornet
viktornet
Flag of United States of America image

how about typecasting?!?!
Avatar of pagladasu
pagladasu

Perhaps you can use templates.
Avatar of Booth882

ASKER

also I want to be able to use it like:

   TypeVar1 AnInt = 88;

I've thought about templates but there are problems with it.  one is that templates must be declared like this:

   type<char> TypeVar1;

which would defeat the purpose of the whole thing.  I would only be able to have TypeVar1 hold char.  any ideas?
a problem with templates is it doesn't hold the type - it's a different class for each type...i guess you could use RTTI, but I forsee a lot of if/else or switch/case if you try this...in the near future

perhaps create a variant class ?

something like

// what type
class Variant_Type
{
public:
enum ETYPE
{
E_CHAR,
E_BOOL,
E_INT,
E_DOUBLE,
// etc
} ;

ETYPE m_etype ; // what type holds

Variant_Type( eType ) { m_etype = eType ; }

void * NewType()
{
switch (m_etype)
{
case E_CHAR : return new char[1] ; break ;
case E_BOOLEAN : return new bool ; break ;
case E_INT : return new int ; break ;
// etc
}
} ;

class Variant
{
private:
Variant_Type m_type :
public:
// etc
} ;


Or if using MFC - they've made one for you - COleVariant
That is not possible, but most likely there is a better way to achieve your ultimate goal.   (answer2000s solution is one, but given more information there is likely to be better solutions.)

So what is it you are ultimately trying to do?
>> do you know a way this can be done?
Not in C++.

Depending on what you want to accomplish you could use templates, RTTI and/or unions.

union types
{
    char char_type;
    unsigned char unsigned_char_type;
    short short_type;
    unsigned short unsigned_short_type;
    int int_type;
    unsigned int unsigned_int_type;
    long long_type;
    unsigned long unsigned_long_type;
    float float_type;
    unsigned float unsigned_float_type;
    double double_type;
    unsigned double unsigned_double_type;
    // etc.
};
yeah I was hoping for something template like... but yeah it seemed to me there was no way to do this either.  

well then if I cant do that, can I have an array of template objects of a different type?  like:

   tem<int> IntTemplate;
   tem<char> CharTemplate;

   tem TemplateArray[] = {IntTemplate, CharTemplate};

is there a way to do this?  maybe with pointers??
You can use a void * pointer, the problem is when you get the object you won't know if it's a char, int, etc. object

A way round this might to be make all our templates derive from a common non-template root class : but if you take this to extremes - this ends up being the same as a variant solution (but with more code)
You can use RTTI

      int i;
      char ch;

      bool fA = (&typeid(ch) == &typeid(char)); // true
      bool fB = (&typeid(i) == &typeid(char)); // false

BTW, the type returned by the typeid operator is const type_info&
How does that help?  

First of all typeid() only works dynamically with classes that have virtual functions.  But more importantly he doesn't need to know an object's type.  We wants to be able change the type assoicated with a storage location.  i.e. declate a variable that stores an int and later change it to store a char--or any other type.
nietods right.  that doesnt help.  what type of information is a type such as 'char'?  is it all in the compiler or is it an actual type, such as kelso said 'const type_info &'.  is there a way I can use that?
The information returned by typeid() is useful for some things, but not really for a lot.  It is best used in a class hierarchy for determining what class you are actually working with when you have a base class pointer.  However, it has lots of limitations, the most important of which is that it is not dynamic, that is the information returned is not dependent on the actual object used at run-time but depends on the type defined at compile-time UNLESS the object is a class with at least one virtual function.  This it tends to be of no value with things like char and int.

Can you give us a better idea of what you are actually tryng to accomplish.?
alright heres what I'm trying to do.  I have a class that interfaces with lots of varied types of a single template class.  like:

   template<class T>
   class B{};

   class A
   {
   private:
      B<int> IntB;
      B<char> CharB;
      B<float> FloatB;
   };

the problem with that is I want it to create and destroy B objects dynamically, so it can grow or shrink.  and I dont want to be set with a predetermined type.  I may not use a certain type in one A object but in another I use three of them.  I thought of making a pointer to a B object for each type, but then I wouldnt be able to have multiple B objects of the same type.  also I would rather not load the class down with excess baggage.  I prefer to have only what is necessary in any class, with the opportunity to make room for things later on if they are needed.  

any ideas on how I could do this?  
It looks as if you need to have all your B-s derived from a single base class, and have A contain a bag of B-s:

template<class T>
class B : public BBase
{
    // ...
};

class A
{
private:
    std::list<B*> itsBs; // you'd probably want some kind of map, so you can access specific B-s
public:
    AddB(B* b);
    // ...
};

Does that help? If this is totally off mark, maybe you can explain more about what A and B stand for.
Oops, I meant:

class A
{
private:
    std::list<BBase*> itsBs;
public:
    AddB(BBase* b);
    // ...
};
can I make BBase nontemplate and B a template???
Yes, that's the idea. In fact, this is a common method to avoid "code bloat" in compilers that do not support separate template compilation: You put all "meaningful" code into a type-neutral base class (eg a list of void*), then derive a template from it, that does mostly type conversions (eg from void* to T*).
If you are programming windows, you may
want to take a look at the documentation of
the Variant type.

This more or less lets you do what you want,
but its not as simple as you want it to be.
altena this was already suggested and dismissed.  thank you though for your help.
yonat - can you put this idea into my generic A and B classes so that I can see its syntax?  feel free to add classes, like BBase or something.  I like the idea I just want to see how it would be done.  then the points are yours.  
OK, here is some code that works on VC6. It is just an illsutration - you probably have different stuff to put insode your B-s.

#include <list>
#include <algorithm>
#include <string>
#include <iostream>
#include <sstream>

class BBase
{
public:
    virtual std::string Value() const = 0; // just an illustration
    // whatever else all B-s has in common as pure abstract functions
    virtual ~BBase() {}
};

template <class T>
class B : public BBase
{
private:
    T itsT; // just an illustration
public:
    B(T t = T()) : itsT(t) {}
    virtual std::string Value() const // just an illustration
    {
        std::stringstream s;
        s << itsT;
        return s.str();
    }

    // ...
};

// small utility class I use - just for the illustrations
template <class Ptr>
class Deleter
{
public:
    void operator()(Ptr p) {delete p;}
};

// another small utility function for illustration
inline void print_B(const BBase* b)
{
    std::cout << b->Value() << std::endl;
}

class A
{
private:
    std::list<BBase*> itsBs;
public:
    void AddB(BBase* b)
    {
        itsBs.push_back(b);
    }

    void PrintAll() // print all itsBs
    {
        std::for_each(itsBs.begin(), itsBs.end(), print_B);
    }

    ~A() // delete all itsBs
    {
        std::for_each(itsBs.begin(), itsBs.end(), Deleter<BBase*>());
    }

    // ...
};

int main()
{
    A a;
    a.AddB(new B<int>(42));
    a.AddB(new B<char>('x'));
    a.AddB(new B<std::string>("Zaphod"));
    a.PrintAll();

    return 0;
}

ah!  beautiful!! :)  that is exactly what I was looking for, thank you yonat.  feel free to answer this question.  
ASKER CERTIFIED SOLUTION
Avatar of yonat
yonat

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks yonat!!!! :)