Click to See Complete Forum and Search --> : Problem with function template
Eisenbart
December 7th, 2002, 09:08 AM
Hi!
I got a problem related to templates, something is not quite working the way it should:
template <int SIZE> void Func( void )
{
cout << SIZE << endl;
}
int main( void )
{
Func<2>();
Func<8>();
}
The output I get is
8
8
and I don't understand why. Shouldn't it be
2
8
as a separate function should be created for each call ???
Mikey
December 7th, 2002, 10:56 AM
try this...
template <class TYPE> void Func(const TYPE& t)
{
cout << t << endl;
}
int main(int argc, char* argv[])
{
Func<int>(2);
Func<int>(8);
return 0;
}
Mikey ;)
Eisenbart
December 7th, 2002, 11:24 AM
Well thanks, but this does not solve my original problem. Consider the following code:
class CAllocator
{
public:
CAllocator( size_t size ) : m_size( size ) {}
~CAllocator() {};
private:
size_t m_size;
};
template <size_t SIZE> CAllocator& GetAllocator( void )
{
static CAllocator inst( SIZE );
return inst;
}
int main( void )
{
GetAllocator<2>();
GetAllocator<8>();
return 0;
}
I need a SEPARATE function to be created for each call to GetAllocator() with a certain size. The idea is to have one CAllocator object for each size, the above code always uses the same function, hence there is only one static CAllocator object, but I need several!
PaulWendt
December 7th, 2002, 02:25 PM
Hello,
What compiler do you have? On Visual Studio .NET, the result is
what you originally expected [I've since uninstalled Visual Studio
6 so I cannot test this code there]. My guess is that it's your
compiler's support for function templates [something Visual
Studio 6.0 wasn't all that great with, which is why I assumed
that]. Anyway, if you DO have Visual Studio 6, make sure that
you have the latest service pack [Service Pack 5].
Edit: Oops, I still have Visual Studio 6.0 installed on another
computer here and I tested the code; it doesn't work even with
Service Pack 5 so you're just plain out of luck unless you upgrade
the compiler. It's time for workarounds :P
--Paul
jfaust
December 7th, 2002, 02:56 PM
This does work, and might be a good workaround:
#include <iostream>
template<int SIZE>
class Test
{
public:
operator()()
{
std::cout << SIZE << std::endl;
}
};
int main()
{
Test<5>()();
Test<8>()();
std::cin.get();
return 0;
}
Jeff
Eisenbart
December 7th, 2002, 03:53 PM
@Paul: Yes, you're right, I use Visual C++ 6.0 and whenever I had a problem it was with templates... I hope there is a cheap upgrade to .net... Anyway, I am glad to hear that it's the compilers fault, not that I'm stoopid or so... ;)
@ jfaust: The workaround looks like it could work, great idea anyway, thanks! :)
Mikey
December 7th, 2002, 10:16 PM
Eisenbart
...
static CAllocator inst( SIZE );
...
but your static CAllocator will not get more instances eventhough it's in a template-class...
Mikey
PaulWendt
December 7th, 2002, 11:46 PM
Originally posted by Mikey
Eisenbart
but your static CAllocator will not get more instances eventhough it's in a template-class...
Mikey
Actually it will:
#include <iostream>
using namespace std;
class CAllocator
{
public:
CAllocator( size_t size ) : m_size( size )
{
cout << "CAllocator::CAllocator(" << size << ")" << endl;
}
~CAllocator() {};
private:
size_t m_size;
};
template <size_t SIZE> CAllocator& GetAllocator( void )
{
static CAllocator inst( SIZE );
return inst;
}
int main( void )
{
GetAllocator<2>();
GetAllocator<8>();
return 0;
}
Output:
CAllocator::CAllocator(2)
CAllocator::CAllocator(8)
Remember, templates actually generate code. Because his
function is templatized, it'll get generated for each template
parameter that's passed into it. It's similar to having a function
overloaded for an int and a char; the compiler also "overloads"
with template parameters.
--Paul
Mikey
December 8th, 2002, 10:30 AM
Originally posted by PaulWendt
Actually it will (...) Because his function is templatized, it'll get generated for each template parameter that's passed into it.
Paul, I copied Your code 1:1 to VC6.
The constructor of CAllocator is only called once and the returned ref.-addresses by GetAllocator<2>() and GetAllocator<8>() are the same.
Though, in VC.NET it's called twice - so it depence on the compiler You use, resp. could be a bug in VC6.
Mikey
jfaust
December 8th, 2002, 10:50 AM
GetAllocator<2>() and GetAllocator<8>() are distinct functions, and the static members should also be distinct. This is a bug in VC6. It's nice to hear they've corrected this in .net.
Jeff
Mikey
December 8th, 2002, 11:42 AM
seems to be a heavy bug in VC6!
replacing PAUL's main()-function with this:
int main( void )
{
CAllocator* pAlloc_1=NULL, *pAlloc_2=NULL;
pAlloc_1 = &GetAllocator<2>();
pAlloc_2 = &GetAllocator<8>();
cout << endl << "Addresses:" << endl;
cout << pAlloc_1 << endl;
cout << pAlloc_2 << endl;
getch();
return 0;
}
Output:
CAllocator::CAllocator(8)
Addresses:
0047DB2C
0047DB2C
If You comment out
pAlloc_2 = &GetAllocator<8>();
the output is
CAllocator::CAllocator(2)!
Eisenbart
December 8th, 2002, 03:55 PM
Yes, it is a bug in VC++ 6.0. I have just downloaded a trial version of the Intel C++ compiler V7.0, and the same code behaves very different there - to be more precise, it works the way it should!
Looks like I should get a new compiler. Intel's compiler seems nice, it also appears to produce faster code, though I haven't really tested it yet...
On the other hand, it does not support all the features I want, at least it does not support the 'export' keyword that can be used with templates...
Some of you seem to possess VC.net - can you tell me wether it supports the 'export' keyword, thus providing for more ansi compliance?
Both VC++ 6.0 and Intel C++ 7.0 reject the following code
export template<class T>
class CSomething
{
};
because of the 'export' keyword.
Mikey
December 8th, 2002, 04:29 PM
export template<class T>
Your code doesn't work in vc.net, also.
jfaust
December 8th, 2002, 04:43 PM
The only compiler I know of that supports 'export' is the Comeau compiler. A recent article by Herb Sutter describes that this doesn't really gain you that much anyway. In other words, you still need to inline your templates.
Jeff
Eisenbart
December 8th, 2002, 05:55 PM
Well, I didn't expect to gain performance or whatsoever, but it better fits my programming style - it sounds childish, but I want .cpp and .h files to come in pairs... :rolleyes:
You do not necessarily have to inline the templates, you just have to put everything into the header files.
jfaust
December 8th, 2002, 10:24 PM
You do not necessarily have to inline the templates, you just have to put everything into the header files.
That's what I meant. I wasn't referring to the 'inline' keyword. I guess I should use a different term ;)
Jeff
Eisenbart
December 9th, 2002, 05:52 PM
Let's say I gotta "infile" the templates... :D
jfaust
December 9th, 2002, 05:58 PM
Hey, I like that. ;)
Jeff
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.