Set of template class

F

Fabien

Hi!

I'm trying to do something that is perhaps impossible to do.

I have two classes : Attribute and SetOfAttributes

Here is Attribute.h

template <typename T>
class Attribute
{
T _value;
};

I'm trying to do this :

class SetOfAttributes
{
std::vector<Attribute> _attributes;
}

int main(...)
{
SetOfAttributes set;
set._attributes.push_back(new ZAttribute<float>());
set._attributes.push_back(new ZAttribute<int>());
}

Which, of course, doesn't work. I can't find the correct syntax to do
it.

Any idea ? Thanks a lot!
 
R

Rolf Magnus

Fabien said:
Hi!

I'm trying to do something that is perhaps impossible to do.

I have two classes : Attribute and SetOfAttributes

Here is Attribute.h

template <typename T>
class Attribute
{
T _value;
};

I'm trying to do this :

class SetOfAttributes
{
std::vector<Attribute> _attributes;
}

int main(...)
{
SetOfAttributes set;
set._attributes.push_back(new ZAttribute<float>());
set._attributes.push_back(new ZAttribute<int>());

What's ZAttribute? Above, you said you have only two classes, Attribute and
SetOfAttributes.
}

Which, of course, doesn't work. I can't find the correct syntax to do
it.

Well, you'd have to make Attribute a non-templated polymorphic class and
derive ZAttribute as a template from it. Then you have to store pointers in
your vector.
Another thing you might be interested in is boost::any.
 
J

Jerry Coffin

@u72g2000cwu.googlegroups.com>, (e-mail address removed)
says...
Hi!

I'm trying to do something that is perhaps impossible to do.

I have two classes : Attribute and SetOfAttributes

Here is Attribute.h

template <typename T>
class Attribute
{
T _value;
};

I'm trying to do this :

class SetOfAttributes
{
std::vector<Attribute> _attributes;
}

Unless SetOfAttributes does more than this, you'd
probably be better off with:

typedef set::vector<Attribute> SetOfAttributes;

If you are going to add more to make it more capable,
then you've got a couple of choices. One is to make
_attributes public (e.g. by making SetOfAttributes a
struct instead of a class). Public data members are
generally regarded as a poor idea though...

Another is to add some (public) member functions to
SetOfAttributes that provide its operations, most of
which will probably just forward to _attributes.
 
F

Fabien

What's ZAttribute? Above, you said you have only two classes, Attribute and
SetOfAttributes.

Sorry, I made a typo, Attribute means ZAttribute to me (I just wanted
to avoid my Z prefix).
Well, you'd have to make Attribute a non-templated polymorphic class and
derive ZAttribute as a template from it. Then you have to store pointers in
your vector.
That's what I did :

class Attribute
{
virtual ~Attribute(void)
{
}
};

template <typename T>
class AttributeT : public Attribute
{
private:
T _value;

public:
inline T getValue(void) const
{
return(_value);
}
};

class SetOfAttributes
{
std::vector<Attribute> _attributes;
};

It works, but I have to cast very often because AttributeT::getValue()
doesn't exist in Attribute. I also wanted to avoid heritage.

I was wondering if there was another solution that I did not know. I
wanted to avoid using Boost, but if it's the only solution to avoid
heritage... why not.

Thanks for your help!
 
F

Fabien

typedef set::vector<Attribute> SetOfAttributes;

Or like this ?

class SetOfAttributes
{
typedef std::vector<Attribute *> TSet;
typedef TSet::const_iterator TConstIterator;
typedef TSet::iterator TIterator;
};
If you are going to add more to make it more capable,
then you've got a couple of choices. One is to make
_attributes public (e.g. by making SetOfAttributes a
struct instead of a class). Public data members are
generally regarded as a poor idea though...

I'd prefer to use OOP and private data members, of course !
Another is to add some (public) member functions to
SetOfAttributes that provide its operations, most of
which will probably just forward to _attributes.

Well, okay, but how should I declare my std::vector to accept many
instances of Attribute with different templates?
 
R

Rolf Magnus

Fabien said:
Sorry, I made a typo, Attribute means ZAttribute to me (I just wanted
to avoid my Z prefix).

That's what I did :

class Attribute
{
virtual ~Attribute(void)
{
}
};

template <typename T>
class AttributeT : public Attribute
{
private:
T _value;

public:
inline T getValue(void) const
{
return(_value);
}
};

class SetOfAttributes
{
std::vector<Attribute> _attributes;
};

It works, but I have to cast very often because AttributeT::getValue()
doesn't exist in Attribute.

Well, there is no useful implementation in the base class, since the return
type depends on the dynamic type, so there is not much you can do about
that.
I also wanted to avoid heritage.

Well, polymorphism is the usual way to go if you want to store objects of
different types in one container.

I was wondering if there was another solution that I did not know. I
wanted to avoid using Boost, but if it's the only solution to avoid
heritage... why not.

You could have a look at boost::any and either use that or take it as an
inspiration for your own implementation.
 
J

Jerry Coffin

@b68g2000cwa.googlegroups.com>, (e-mail address removed)
says...
Or like this ?

class SetOfAttributes
{
typedef std::vector<Attribute *> TSet;
typedef TSet::const_iterator TConstIterator;
typedef TSet::iterator TIterator;
};

What good is class SetOfAttributes if all you put into it
is typedefs? All you're defining is names, so if you
don't want them to be visible globally, you probably want
to put them into a namespace rather than a class.

[ ... ]
Well, okay, but how should I declare my std::vector to accept many
instances of Attribute with different templates?

Ah, now we get to the crux of the situation: you want to
create an array of heterogeneous objects. The answer is
that you shouldn't even attempt to do that -- no matter
how you try to do it, it's going to cause a problem. Your
_only_ real choice is to make everything in the vector
the same type. They might be (smart) pointers to objects
of different types, but the things you actually put into
the vector really all need to be the same type.

From there you have a couple of choices: you can store
pointers to completely unrelated types, with some
intelligence to get the original type of object back when
you need it, or you can store a pointer to a base class,
and (when necessary) have it point at instances of
derived objects.

An entirely different possibility is to simply store the
different types of objects separately from each other. If
you have a relatively small set of types to deal with,
this may be the cleanest method available.

From the sound of things, your design may simply need
more thought. I'm not sure whether you're better off
doing that on your own, or posting more about the problem
here, and having us help out, but it sounds like right
now your problem goes far beyond mere syntax.
 
F

Fabien

Thanks for your help! I know I can't store objects of different types
in the same container, but since it was a problem of template, I
thought there might be a hidden solution.

I'll go with polymorphism and come back to you if I have problems using
dynamic and const cast.

Thanks again.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top