|
-
December 7th, 2002, 10:08 AM
#1
Problem with function template
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 ???
-
December 7th, 2002, 11:56 AM
#2
try this...
Code:
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
-
December 7th, 2002, 12:24 PM
#3
Well thanks, but this does not solve my original problem. Consider the following code:
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!
-
December 7th, 2002, 03:25 PM
#4
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
-
December 7th, 2002, 03:56 PM
#5
This does work, and might be a good workaround:
Code:
#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
-
December 7th, 2002, 04:53 PM
#6
@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!
-
December 7th, 2002, 11:16 PM
#7
Eisenbart
...
static CAllocator inst( SIZE );
...
but your static CAllocator will not get more instances eventhough it's in a template-class...
Mikey
-
December 8th, 2002, 12:46 AM
#8
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:
Code:
#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
-
December 8th, 2002, 11:30 AM
#9
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
Last edited by Mikey; December 8th, 2002 at 11:34 AM.
-
December 8th, 2002, 11:50 AM
#10
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
-
December 8th, 2002, 12:42 PM
#11
seems to be a heavy bug in VC6!
replacing PAUL's main()-function with this:
Code:
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)!
-
December 8th, 2002, 04:55 PM
#12
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
Code:
export template<class T>
class CSomething
{
};
because of the 'export' keyword.
-
December 8th, 2002, 05:29 PM
#13
No,
Your code doesn't work in vc.net, also.
Last edited by Mikey; December 8th, 2002 at 05:39 PM.
-
December 8th, 2002, 05:43 PM
#14
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
-
December 8th, 2002, 06:55 PM
#15
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... 
You do not necessarily have to inline the templates, you just have to put everything into the header files.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|