Sign in to follow this  

Template question (C++ durr)

This topic is 3408 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok so I finally started getting into mettaprograming and have come upon something that should be do-able, but I can't seem to get my compiler (or google) to really go along with what I'm trying to do. Can I set up a map / list / stl container of Template pointers, and then specify the class at insert time? ie: std::map<int,MyTmplate*> mpTmplate; mpTmpltate* = new MyTmplate<int>(); Or similar.... OR do I need to make a abstract base class with my template as a member and interface it that way? (with a different subclass for each type I might use with my template) ...seems to me that this is sort of redoing the work that templates would have allowed me to only do once.

Share this post


Link to post
Share on other sites
The code example you gave is confusing, because it's quite incomplete and doesn't clearly demonstrate what you're trying to do.


Are you trying to make a 'template typedef', like:

typedef std::map<int, T*> TPtrMap;

TPtrMap<int> t; // where t is a map<int, int*>

?

If so, then no, you cannot do this until C++0x:
http://en.wikipedia.org/wiki/C%2B%2B0x#Template_typedefs

Share this post


Link to post
Share on other sites
Unfortunately I'm not really certain what you're trying to do, but I do have a question:

What is the actual, practical, problem you're trying to solve? As opposed to the non-contextual problem you presented.

Edit:
Ah, RDragon1 might have hit on what you're trying to do. Real templated typedefs don't exist yet but there are two main workarounds:

- Stick the typedef in a templated struct:

template <class T>
struct MyTemplate
{
typedef std::map<int, T> type;
};

MyTemplate<int>::type myIntMap;
MyTemplate<float>::type myFloatMap;

- Use 'empty' inheritance:

template <class T>
struct MyTemplate : std::map<int, T> { };

MyTemplate<int> myIntMap;
MyTemplate<float> myFloatMap;

Share this post


Link to post
Share on other sites
Sorry for my overly abstract example.

My actual template:


template<class T> class LabelAndValue
{
public:
LabelAndValue(){}
LabelAndValue(std::string stLab){stLabel = stLab;}
std::string stLabel;
T tValue;
void GuiGramAdd(GuiMessenger::GuiGram ggIn);
std::string GetFormatedString();
};





I then want to have a map of my LabelAndValue Template where I don't know what the type of tValue will be before hand (either int, float or std::string atm). The map will be filled at load time from an XML file which specifies the stLabel and the type of the value. The value can change during run time through the GuiGramAdd function (which I have made versions of for int / float and std::string).

That is my specific reason for wanting to do this atm, but I am less interested in other ways to solve that specific problem as to whether this is something I can do with templates.

Edit: speedy replies tonight, no I'm not trying to do a template typedef as RDragon1 suggested.

Share this post


Link to post
Share on other sites
you'll find that the compiler will claim that LabelAndValue<int> is a totaly different type from LabelAndValue<float>, of course the easy way around this is to simply have a base class which isn't templated, e.g. AbstractLabelAndValue, but then you lose most of the benefit of having the template class.

is this class purely for display purposes? if so, simple inheritence may be sufficient.

also, look into boost::any and similar containers. although, they are also prone to type-saftey issues.

Share this post


Link to post
Share on other sites
Templates are resolved statically at compile time whereas reading from an XML file is a dynamic, run-time, operation. What I'm saying is that they're different beasts.

If your LabelAndValue can have a non-templated base class then you could store pointers to the base class and use it polymorphically, i.e.

template<class T>
class LabelAndValue : public LabelAndValueBase { /*...*/ }

std::map<int, LabelAndValueBase*> labels;

labels[5] = new LabelAndValue<int>;


But then you have to suffer with the non-templated base class.

Sometimes this a genuine problem, that is to say it's not a design flaw, and in those cases there is always boost::any and boost::variant.

I'd like to take a different approach to this issue though. Generally speaking the value stored in a label is maintained as text; it doesn't matter to the label whether that text happens to be interpreted as an integer or decimal later on. So you can probably do just fine by storing only a std::string as the value type and ditching the template idea.

For converting a string into a numeric type I'd recommend either boost::lexical_cast or std::stringstream.

Share this post


Link to post
Share on other sites
Yeah that was sort of what I was thinking hand have already started on an abstract class that is simply an interface to this template.

Thanks for your time.
-vs

Edit to dmatter: The value and label are entirely different things, I am trying to make a data driven system (much more then necessary): I'm just trying to do a simple way of saving / and formatting things along the lines of "Name: Hiro Protagonist", "Age: 30" something along those lines.

And yeah I have been using std::ostringstream for some time (after finally breaking my bad sprintf habit);

2nd Edit to dmatter: after going back to my code I realized you were talking about the value weren't you? sry that I missed your point. Actually for this class I am working on it will work just fine if both label and value are stored as strings... man that simplifies things.

[Edited by - vs322 on August 11, 2008 9:55:19 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by vs322
Edit to dmatter: The value and label are entirely different things
To check we're on the same page: Presumably the value is the text that goes 'in' the label and each label has a name?

Quote:
I am trying to make a data driven system (much more then necessary): I'm just trying to do a simple way of saving / and formatting things along the lines of "Name: Hiro Protagonist", "Age: 30" something along those lines.
My interpretation is that 'Name' and 'Age' are the names of two labels, and 'Hiro Protagonist' and '30' are the values of those labels respectively. A useful thing to note is that just because we as humans see '30' as an integer doesn't mean it has to stored as an int. It would simplify things for you to just say that the value of a label is text so store it all as a std::string.

Share this post


Link to post
Share on other sites

This topic is 3408 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this