Archived

This topic is now archived and is closed to further replies.

C++ Template Parameters

This topic is 5114 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

Hey all, Short and simple question - I want to do something like the following: template< class T, int i > class MyClass ... implementation follows with type T and int i used ... and later on: MyClass< Object, 1 > my_class_instance; --- Now that works okay, but I want to know if anybody can help with doing something similar, except using a string as a template parameter? Would it be possible to rework MyClass'' definition so that I can use it like: MyClass< Object, "OBJ" > my_class_instance; If this is possible, please explain to me as all my various attempts have resulted in issues regards, GeniX www.cryo-genix.net

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
What ''issues'' have you hit & what did you try? did you use STL strings? or perhaps a char* ? I can''t think of any reason why a string/char* should fail systematically (I''m forever using stl strings in vectors/lists/maps) so I can''t help thinking it must be to do with how you''re implementing it.

Share this post


Link to post
Share on other sites
Well, I have tried using a number of template definitions:

-------
template< class T, std::string name >
is not liked at all. It doesnt want the std::string as a template parameter. Cant get this going.

template< class T, char name[] >
is allowed, but there are restrictions on what can be passed in for the name parameter.

template< class T, char* name >
similar to above.
-------

I tried placing ''const'' keywords in front of the parameter names to see if it made a difference. It didnt have any effect (but I didnt think it would anyway).

If I use the template parameter of char* or char[], then I can use it as follows:

char global_name = "OBJ";

void main()
{
MyClass< int, global_name > my_class;
}

But the global_name has to be global var, and non-const. It *doesnt* work if I use:
const char global_name = "OBJ";

and it *doesnt* work if I dont use global_name, and just inline the name like:
MyClass< int, "OBJECT" > my_class;

Pretty much it only wants to accept a globally accessible named variable as a parameter - no inline stuff (which in hindsight is understandable).






regards,

GeniX

www.cryo-genix.net

Share this post


Link to post
Share on other sites
It''s possible, but fairly annyoing, non-intuitive and basically not worth the bother to template off of a string.

For example: this will compile and run in MSVC .NET 2003

template <const std::string & T>
class A {
public:
void out(void) {
std::cout << T << std::endl;
}
};

extern const std::string str("STR");

int main(void) {
A<str> a;
a.out();

return 0;
}

Non-type, non-integer template arguments must be taken by reference, hence the std::string &. They can only be instatiated by a reference with external linkage, which is why str is declared outside the function.

However, there is a problem. Even if the template arguments have the same logical value, templating off of two different string variables will refer to different class types. That is to say A<str1> and A<str2> are different types even if str1 == str2.

Share this post


Link to post
Share on other sites
Yeah, I think the std::string example is similar to what I found with the char[] example. I need to pass in a named variable which is globally accessible.

That is too much of a pain in the butt for what I am wanting to do. THe purpose of me intending to do it in the template parameter was for neater coding so the name could be a template parameter.

Thanks for the insight.





regards,

GeniX

www.cryo-genix.net

Share this post


Link to post
Share on other sites
What do you need this for? There may be other ways to accomplish this.


"Sneftel is correct, if rather vulgar." --Flarelocke

Share this post


Link to post
Share on other sites
SiCrane, allow me to revoke my thanks partially! I had not tested your code.

I am running VS.NET, and it will not compile your code because it says:
"reference template parameters are not supported"

Perhaps I have an earlier version of .NET

---

Sneftel: I have various serialiser classes for serialising objects. I wanted to write a serialiser class that will serialise a std::list, and use whatever serialiser is needed for the type of object stored in the list. My idea was to use:

new MyListSerialiser< int, "INT" >

which would create a list serialiser to serialise a list of ''int''s, assuming that the name of the serialiser needed to serilise the contents of the lists (ie: the ints) is called "INT". And I was hoping that if the "INT" were const, that I could use the ## operator to implement the GetName() function for my list serialiser.

So with a template parameter of "INT", the list serialiser would automatically return "LISTINT" using ## to join the names at compile time.

There is another way of doing it, and I have done so - which is to pass the "INT" in as a parameter to the MyListSerialiser constructor. This has the downside that "INT" is stored in the MyListSerialiser and any operations using it are not done compiletime, but involve std::string constructors and the like for joining on the "LIST" to form "LISTINT".

Hope I explained that well enough



regards,

GeniX

www.cryo-genix.net

Share this post


Link to post
Share on other sites
Yes, parameterizing templates on references is not supported on the first MSVC .NET compiler. Support was added to MSVC in version 7.1 a.k.a. .NET 2003.

Also, even if you succeeded in getting a string as a template parameter, you still would not be able to use ## to concatonate the string. As a string object it would still obey all the normal rules of C++''s type system.

Share this post


Link to post
Share on other sites
''tis true. I wanted to get the char[] style parameter working so I could try the ##. With strings, I''d not be able to use the ##.

Are reference parameters in a template definition supported on other standards complient compilers? Is this behaviour a feature of the newer .NET compiler, or is it that .NET is finally implementing template functionality that should have been there all along?



regards,

GeniX

www.cryo-genix.net

Share this post


Link to post
Share on other sites
Even if you had gotten the char[] style template to work, you still couldn''t have used ##.

And template parameters of reference types are in the C++98 standard. (Though it isn''t widely supported.)

Share this post


Link to post
Share on other sites