C++ question on templates

I have a class template like:

class A {};
template class B : publc A {};;

in my code (not within either class) I have a vector of class A objects, which where cast from the B objects. This just allows me to have a vector of mixed template objects. For instance:

B aa;
B bb;
vector vectorOfA;
vectorOfA.push_back( A(aa)); // cast B type object to A
vectorOfA.push_back( A(bb));

Then I want to do something like this:
B* temp = vectorOfA.at(0);

The problem I’m having is that I need the data type from the first entry. Is there a way to create a variable that is itself a data type? Such that I could do something like:
B< vectorOfA.at(0)->GetDataTypeOfThisTemplate() >* temp = vectorOfA.at(0);

Or is there some other solution I’m not aware of?

Thanks for any help

[quote]This just allows me to have a vector of mixed template objects. [/quote]Actually your code does not allow you to mix objects. vectorOfA.push_back( A(aa)); // cast B type object to A This is not a cast but instead this is a ‘splice’ only the A part is copied into the vector. This is because you have a vector, i.e. a vector of object exactly of type A. Instead you were thinking of a vector<A*> (or if you class inherit from TObject a TObjArray)

B< vectorOfA.at(0)->GetDataTypeOfThisTemplate() >* temp = vectorOfA.at(0); It is possible to retrieve the actual type of a pointer (TClass has an interface to give the information or an object inherited from TObject can use the IsA() method), however you would not be able to use this information at compile time … since by definition this is run-time information. So you would not be able to use the paradigm you describe (well technically if you were using vector<B > and vector<B > you could write templated function that would behave in a way similar to what you describe …
On the other hand, usually if you use a vector<A*> it is because the interface ‘A’ has enough richness (i.e. enough virtual function) so that you can use the A without having to know their actual types.

I think you need to take a step back and look of what you are trying to achieve in the first place and decide then on the best solution. In short why (for what purpose) do you need to know the actual type of the elements.

Cheers,
Philippe.

Thanks for your response.

Yes, that was a typo, I am using a vector of pointers.

Let me get more detailed. I’m trying to access attributes of the ATLAS Cool database (if that helps).

This involves using a function that itself is a template. So you call:
payloadValue(“attributeName”);
And this returns the value of the attribute you are requesting from the database.

So I have this class, CoolAttr, which I attached. There is also CoolAttrBase, which I am using to fill the vector. They are very simple classes as you can see. I just want to hold a attribute name as a string and the value itself.

So in the end I need to pass the data type to this template function. I also cannot put a virtual getAttr or setAttr function in the base class because they use the template dataType value.

Does this information help? Or am I just stuck and should try something else.
CoolAttr.h (942 Bytes)

Hi,

hmm, if I understand your postings correctly then that’s a totally different question than your first one :slight_smile: You can do

T get<T>(const char* name) { return payloadValue<T>(name); } to solve your second issue, i.e. you’ll have to “stay at the template level”. You can do B<int>* bi = dynamic_cast<B<int>* >(vectorOfA.at(0);) to test whether it contains ints.

Depending on your exact use case it might be faster (talking runtime here) to include a virtual function in A which signals the derived class’s template parameter type, e.g. by returning an enum constant, like to:

[code]class A {
public:

enum EContaineeType {
kInt,
kFloat,

kNumContaineeTypes;
};

virtual EContaineeType getContaineeType () const = 0;
};

template
struct TypeToEContaineeTypeMap {};

template <>
struct TypeToEContaineeTypeMap {
enum { kContaineeType = A::kInt }; };
//and all the other cases you have

template
class B: public A {

EContaineeType getContaineeType () const {
return (EContaineeType) TypeToEContaineeTypeMap::kContaineeType;
}
};
[/code]
Like that you could do

switch (a->getConteineeType()) { case A::kInt: ... }

Cheers, Axel.