Problems using function templates

F

Fred H

I'm currently trying to write a function template that
can fill a variable of arbitrary type with 'random' stuff,
but I can't seem to get my function template working.

In my .h file I've declared the function template like this,
inside a class I'm building:

template <typename T> T RandBits();

In my .cpp file I've implemented it like this:

/* Function: RandBits */
template <typename T> T hdd::HexGen::RandBits() {
T bits = T();
for(int i = 0; i < sizeof(T); i++) {
bits <<= 8; //Left shift by 8
bits |= rand() % 0xFF; //Insert 8 'random' bits
//printf("%08X\n",bits); //Shows the progression
}
return bits;
}//EndOf RandBits()

Even though the FAQ says I should use 'extern', I've omitted
it, because I get an error message using it.

I don't get any linking errors, but as suggested by the FAQ,
I've included the following in the same .cpp file:

template hdd::HexGen::RandBits<int>();

Now, in another .cpp file, where I've got my main, I
instansiate an object of my class, and call the template
function like this:

long lngRand = hg.RandBits<long>();
cout << "\n" << hex << lngRand << endl;

'hg' is of course a object of the mentioned class.

Using VS VC 6.0 SP5(?), I get the following error:

c:\programfiler\microsoft visual
studio\myprojects\tutorialtests\myxor\main.cpp(12) : error C2062: type
'long' unexpected

Why is 'long' unexpected? Can anyone see what I'm doing wrong? I suppose
I've stared myself blind on this problem by now, so all inputs are
appreaciated :)

--
Fred H

void FredH::Contact() {
TextToSpeach.say("frode at age dee dee dot en oh");
}
 
P

Patrik Stellmann

Fred said:
In my .cpp file I've implemented it like this: [...]

Even though the FAQ says I should use 'extern', I've omitted
it, because I get an error message using it.

If you place the implementation in a cpp-file the compiler can't find it
when generating code with it. If the 'extern' doesn't work (I actually
naver used it) place the implementation on the bottom of your
header-file or (as I prefer) in a hexgen.inl file and place an
#include "hexgen.inl"
at the bottom of your header.

Another problem is that the VC compiler (at least 6.0, 7.0 and 7.1) do
not support explicite template specification so you might have to
rewrite your function to something like

template <typename T> T hdd::HexGen::RandBits(T& BitsRef)
{
[...]
}
 
L

Loran Hayden

I believe templates must be defined within the header files, not in .cpp
files.
 
F

Fred H

template hdd::HexGen::RandBits<int>();

This statement obviously lacks a return statement.
When I insert one, I actually gets more error messages:

c:\programfiler\microsoft visual
studio\myprojects\tutorialtests\myxor\hexgen.cpp(30) : fatal error C1001:
INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1794)

c:\programfiler\microsoft visual
studio\myprojects\tutorialtests\myxor\main.cpp(12) : error C2062: type
'long' unexpected
Error executing cl.exe.
 
F

Fred H

Another problem is that the VC compiler (at least 6.0, 7.0 and 7.1) do
not support explicite template specification so you might have to
rewrite your function to something like

This, of course (shame on MS VC 6.0!!!), fixed the problem. It was
my lame compiler that, as you said, didn't support explicite template
specification.

But I also tried using gcc under Linux, and still I got error messages.
So even though at least on of the reasons I got error messages using VC
was that VC does not support explicit template specification, there
seems to be even more wrong with my code...


--
Fred H

void FredH::Contact() {
TextToSpeach.say("frode at age dee dee dot en oh");
}
 
P

Patrik Stellmann

But I also tried using gcc under Linux, and still I got error messages.
So even though at least on of the reasons I got error messages using VC
was that VC does not support explicit template specification, there
seems to be even more wrong with my code...
Would help if you post then those error messages (with lines in which
they occure)...
 
C

Chris Theis

Fred H said:
This statement obviously lacks a return statement.
When I insert one, I actually gets more error messages:

c:\programfiler\microsoft visual
studio\myprojects\tutorialtests\myxor\hexgen.cpp(30) : fatal error C1001:
INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1794)

c:\programfiler\microsoft visual
studio\myprojects\tutorialtests\myxor\main.cpp(12) : error C2062: type
'long' unexpected
Error executing cl.exe.

The problems you're facing are due to the shortcoming of the VC++ 6.0
compiler regarding templates. However, it can easily be solved by moving the
template declaration from the function to the class, which IMHO makes more
sense anyway. Furthermore it is good practice to implement templates in the
context of the header file and not the .cpp/.cc/.cxx file. There are some
cases using VC++ where separating declaration & definition of templates will
get you strange errors.

namespace hdd {
template<typename T>
struct HexGen {
T RandBits()
{
T bits = T();
for(int i = 0; i < sizeof(T); i++) {
bits <<= 8; //Left shift by 8
bits |= rand() % 0xFF; //Insert 8 'random' bits //
NOTE: Did you call srand() once beforehand?
}
return bits;
}//EndOf RandBits()
};
}

Regards
Chris
 
F

Fred H

The problems you're facing are due to the shortcoming of the VC++ 6.0
compiler regarding templates.

I'm starting to realise this...
However, it can easily be solved by moving
the template declaration from the function to the class ...

Ok? It's just that I'm not using templates for the class. Only
for the function. (But I've started putting the template def
in the header file, and not using explicit specification, and
now it works. But...see next paragraph.)
Furthermore it is good practice to implement templates in the context of
the header file and not the .cpp ...

But the FAQ suggests that this can cause "significant code bloat".
How about that?

Thanks for all the input btw, all of you :)

--
Fred H

void FredH::Contact() {
TextToSpeach.say("frode at age dee dee dot en oh");
}
 
T

tom_usenet

I'm starting to realise this...


Ok? It's just that I'm not using templates for the class. Only
for the function. (But I've started putting the template def
in the header file, and not using explicit specification, and
now it works. But...see next paragraph.)


But the FAQ suggests that this can cause "significant code bloat".
How about that?

This bloat occurs on compiler/linker combinations that aren't able to
coalesce instantiations of template specializations from different
translation units into a single definition of the specialization in
the final executable. The only system that I have used that has this
problem is GCC on qnx-nto. I doubt you're using anything so obscure!
MSVC, Borland, GCC on normal platforms, Intel, Metrowerks, etc., etc.
don't have this problem - they combine instantiations.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 
F

Fred H

MSVC, Borland, GCC on normal platforms, Intel, Metrowerks, etc., etc.
don't have this problem - they combine instantiations.

I kind of recconed that they did, but it's good to have it confirmed.

Thanks!


--
Fred H

void FredH::Contact() {
TextToSpeach.say("frode at age dee dee dot en oh");
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,160
Messages
2,570,889
Members
47,420
Latest member
ZitaVos505

Latest Threads

Top