• Advertisement

Archived

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

Can you Template a Template....

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

Hi, I just started using the STL, and have ran into a problem. I am trying to write a templated function that has an std::map as one of its parameters. Here are the functions.
    
#include< iostream.h >
#include< stdlib.h >
#include< map >


template < class T > SetEntry( std::map< char*, T > &Map, char *sEntryName, T iValue )
{
	Map[sEntryName] = iValue;
	return NULL;
}

template < class T > GetEntry( std::map< char*, T > Map, char *sEntryName )
{
	return Map[sEntryName];
}

  
When I call the functions as follows, with type int, they work fine
    
	std::map< char*, int >Script;

	SetEntry( Script, "Var1", 56 );
	SetEntry( Script, "Var2", 17 );
  
however when I try and use them with type float
    
	std::map< char*, float > Script;

	SetEntry( Script, "Var1", 11.66 );
	SetEntry( Script, "Var2", 66.11 );
  
I get the following Coliple Errors. The only reason I can think is that map is itslef a template, and I am trying to template this..... or something wierd like that.
    
--------------------Configuration: stl - Win32 Debug--------------------
Compiling...
main.cpp
C:\Windows\Desktop\stl\main.cpp(20) : error C2782: 'int __cdecl SetEntry(class std::map<char *,T,struct std::less<char *>,class std::__default_alloc_template<0,0> > &,char *,T)' : template parameter 'T' is ambiguous
        could be 'int'
        or       'float'
C:\Windows\Desktop\stl\main.cpp(21) : error C2782: 'int __cdecl SetEntry(class std::map<char *,T,struct std::less<char *>,class std::__default_alloc_template<0,0> > &,char *,T)' : template parameter 'T' is ambiguous
        could be 'int'
        or       'float'
Error executing cl.exe.

main.obj - 2 error(s), 0 warning(s)
          
Any ideas would be greatly appreciated. Thanks Giant "Only two things are infinite, the universe and human stupidity, and I'm not sure about the former." --Albert Einstein [edited by - giant on April 18, 2002 6:15:39 AM] [edited by - giant on April 18, 2002 6:16:06 AM] [edited by - giant on April 18, 2002 6:16:29 AM] [edited by - giant on April 18, 2002 6:16:46 AM] [edited by - giant on April 18, 2002 6:17:06 AM] [edited by - Oluseyi on April 18, 2002 6:38:00 AM] [edited by - giant on April 18, 2002 6:46:51 AM]

Share this post


Link to post
Share on other sites
Advertisement
Are you using MS? If so, give your compiler a helping hand by letting it know exactly which types you are talking about. If it sees this code:

std::map< char*, float > Script;

Then it sees that you have instantiated your map with a float type. In SetEntry, the third parameter type has to match the 2nd parameter type of your map. If you then say:

SetEntry( Script, "Var1", 10 );

The number 10 is of int type, but the map stated a float type. The compiler gets confused because it doesn''t know which type you really mean. So, what you need to do is tell it which type you intended, by doing this:

SetEntry( Script, "Var1", 10.0f );

The compiler should really be able to tell which type you are after, as there is a conversion path from int to float, but MS''s compiler isn''t too great on template type deduction.

I also noticed a couple of other things with your code:

1. Use the header iostream rather than iostream.h. The latter is non-standard;

2. You are missing return types on your functions. It shouldn''t compile because of that, but this is probably MS''s compiler we''re talking about.


[C++ FAQ Lite | ACCU | Boost | Learning C++]

Share this post


Link to post
Share on other sites
The function is expecting T to be a float, but you are passing it a double.


      
std::map< char*, float > Script;
SetEntry( Script, "Var1", 11.66 );
SetEntry( Script, "Var2", 66.11 );

// should be:


std::map< char*, float > Script;
SetEntry( Script, "Var1", 11.66f );
SetEntry( Script, "Var2", 66.11f );


Remember the default type of a decimal number is a double. If you want it to be a float, you have to specify it as such.

EDIT:

I just noticed that it was complaining that it thought T was an int. It is probably confused because you haven't specified a return type (default return type is int)

[edited by - Sandman on April 18, 2002 6:56:26 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by SabreMan

I also noticed a couple of other things with your code:

1. Use the header iostream rather than iostream.h.
The latter is non-standard;



Who cares.

Share this post


Link to post
Share on other sites
Hi Guys.
Thanks a lot for your help, it was really useful.
SabreMan, to my extreem Embarrassment, that is the actual code. I cant believe that I forgot to include the return types. I was so concerned about setting up the templace correctly that I forgot one of the most basic programming constructs.

I hang my head in shame.

Thanks again Guys.

Giant

"Only two things are infinite, the universe and human stupidity, and I''m not sure about the former." --Albert Einstein

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster

Who cares.



People who want to be able to predict what the header actually contains.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
Who cares.

What''s your problem?

quote:
Original post by giant
SabreMan, to my extreem Embarrassment, that is the actual code.

Then it wasn''t the actual error message.
quote:

I cant believe that I forgot to include the return types. I was so concerned about setting up the templace correctly that I forgot one of the most basic programming constructs.

Everyone makes simple mistakes now and again. It''s rather annyoing that MS''s compiler doesn''t warn against this.


[C++ FAQ Lite | ACCU | Boost | Learning C++]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by SabreMan
[quote]Original post by Anonymous Poster
Who cares.

What''s your problem?


i think "it''s non-standard" is not a satisfying answer.
it should be explained why one should use the "namespaced"
includes, there should be more of an answer than just
"it''s non-standard"
(ie. i heard it can cause trouble to use old style
headers in conjunction with stl.
dunno for myself, don''t use them)


Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
i think "it's non-standard" is not a satisfying answer.


"who cares" does not convey that concern. If you'd have asked something like "why is that a problem", I would have understood your concern. However, I do not think it is practical to provide a full explanation each and every time I see someone using "iostream.h".
quote:

it should be explained why one should use the "namespaced"
includes, there should be more of an answer than just
"it's non-standard"

Very well. The difference between iostream.h and iostream is not just that iostream is namespaced. You are thinking of the C headers included into C++ for C compatibility, with namespaced versions that drop the ".h" and add a leading "c" to the name of the header. iostream.h is different.

It's not an old c header, and it has *never* been incorporated into the C++ standard. That means that the contents of iostream.h can vary from compiler-to-compiler, if your compiler even defines it. Coding in terms of the standard headers helps to ensure you are not inviting errors into your code, it helps keep your code portable, it increases the number of accurate reference sources applicable to your code, and it helps us on the forums to know exactly what your code should be doing when you need to post it. If you compare all that to the effort required to use iostream (you drop the ".h" and use namespace std), I think most people would agree there is no reason to use iostream.h.
quote:

(ie. i heard it can cause trouble to use old style
headers in conjunction with stl.
dunno for myself, don't use them)

One example is that MS's iostream.h does not include an operator<< for std::string.


[C++ FAQ Lite | ACCU | Boost | Learning C++]

[edited by - SabreMan on April 18, 2002 9:04:12 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
hey, sabre, thanks for detail explanation!
And I didn''t know it can vary between compilers.

well, the "who cares" was just the answer to
"it''s non standard", well, if that was the only thing,
I''d say, wasn''t too bad, if the code works good,
who cares if it''s standard or not...


however, yeah, it''s good to just link to iostream,
and know you don''t have to worry about other issues

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
i care...

my code has to work on freebsd, openbsd, slackware, red hat, and debian, as well as windows

standards are nice, don''t ignore them

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
ha! now 2 APs here :-)

however, I meant to say "include" instead of "link to"

Share this post


Link to post
Share on other sites

  • Advertisement