Unresolved External Symbol - problem with template class

K

Kefik

Hi, I'm new to C++ so may be this is a trivial problem but...

I'm trying to create a template class, in header file I declared it
and in source file implement, seems nice, but linker won't link
constructors and destructors as I'd like him to do.

To demonstrate problem, I'm trying to compile this...

------------------------
my.h:

template <class A> class my{

public:

my<A>();
~my<A>();

};
-------------------------
my.cpp:

#include "my.h"

template <class A> my<A>::my(){};
template <class A> my<A>::~my(){};
--------------------------
main.cpp:

#include "my.h"

int main(int argc, char* argv[])
{

my<int> b;
// linker error, Unresolved External Symbol "public:__thiscall
my<int>::my<int>(void)" .... referenced in function
_main

return 0;
};

--------------------


More strange thing to me appears (that's why I'm out of ideas) that
this works fine with non-template classes.

What's wrong?

THX in advance for any ideas.
 
L

Larry Brasfield

Kefik said:
Hi, I'm new to C++ so may be this is a trivial problem but...

I'm trying to create a template class, in header file I declared it
and in source file implement, seems nice, but linker won't link
constructors and destructors as I'd like him to do.

To demonstrate problem, I'm trying to compile this...

------------------------
my.h:

template <class A> class my{

public:

my<A>();
~my<A>();

};
-------------------------
my.cpp:

#include "my.h"

template <class A> my<A>::my(){};
template <class A> my<A>::~my(){};
--------------------------
main.cpp:

#include "my.h"

int main(int argc, char* argv[])
{

my<int> b;
// linker error, Unresolved External Symbol "public:__thiscall
my<int>::my<int>(void)" .... referenced in function
_main

return 0;
};

--------------------


More strange thing to me appears (that's why I'm out of ideas) that
this works fine with non-template classes.

What's wrong?


Your code compiles fine with the v7.1 compiler.
If my memory serves me correctly, (not a foregone
conclusion!), some earlier, less C++ compliant
version of the compiler had trouble with the
redundant member name syntax you used.
Try changing your class definition to:
template <class A> class my{
public:
my();
~my();
};
 
A

Antti Keskinen

Hi !

This code - with these precise files - will, as far as I know, compile only
with Comeau C++ compiler. The problem is that the template class' member
function declarations and definitions are in a seperate file. They must not.
In Visual Studio 6, 7 and 7.1, the template definitions must be in the same
file as the declarations, and this whole package must be completely visible
in every compilation unit where this template is needed to be instantated.

In english, it means that the "my.cpp" file must be removed, and the
template class' constructor and destructor definition code must be moved to
"my.h", either underneath the template declaration, or as part of it. Then
the "main.cpp" must include the "my.h" file. After these changes, it will
work.

If you use the Comeau C++ compiler, you must use the 'export' keyword with
the templates. Currently, this compiler is the only one that recognizes this
keyword and treats it as per C++ Standard. There are reasons why Visual C++
compiler doesn't support it, and probably never will. It's not because the
compiler was buggy: it is because supporting the keyword doesn't have as
long-range benefits as the users expect it to. For example, even with the
keyword, if you build a template library, you must still provide the
definitions of each template that is going to be instantated. The standard
ideology of ".lib, DLL and a header" doesn't work with templates. It just
does not. Not even with Comeau C++.

-Antti Keskinen


Larry Brasfield said:
Kefik said:
Hi, I'm new to C++ so may be this is a trivial problem but...

I'm trying to create a template class, in header file I declared it
and in source file implement, seems nice, but linker won't link
constructors and destructors as I'd like him to do.

To demonstrate problem, I'm trying to compile this...

------------------------
my.h:

template <class A> class my{

public:

my<A>();
~my<A>();

};
-------------------------
my.cpp:

#include "my.h"

template <class A> my<A>::my(){};
template <class A> my<A>::~my(){};
--------------------------
main.cpp:

#include "my.h"

int main(int argc, char* argv[])
{

my<int> b;
// linker error, Unresolved External Symbol "public:__thiscall
my<int>::my<int>(void)" .... referenced in function
_main

return 0;
};

--------------------


More strange thing to me appears (that's why I'm out of ideas) that
this works fine with non-template classes.

What's wrong?


Your code compiles fine with the v7.1 compiler.
If my memory serves me correctly, (not a foregone
conclusion!), some earlier, less C++ compliant
version of the compiler had trouble with the
redundant member name syntax you used.
Try changing your class definition to:
template <class A> class my{
public:
my();
~my();
};
 
K

Kefik

Larry Brasfieldwrote:
Kefik said:
Your code compiles fine with the v7.1 compiler.
If my memory serves me correctly, (not a foregone
conclusion!), some earlier, less C++ compliant
version of the compiler had trouble with the
redundant member name syntax you used.
Try changing your class definition to:
template <class A> class my{
public:
my();
~my();
};

I have got MS Visual C++ .NET (v7.1.3088) seems it's the same compiler
as you have... and with <A> or without I still get this linker
problem, now I'm confused little more. May be some strange linker
options?
 
K

Kefik

Hi, well that's interesting, I've found templates fascinating, but
now, I don't know what to think about them, do you think it's better
not to use them at all?
Antti Keskinenwrote: Hi !

This code - with these precise files - will, as far as I know, compile only
with Comeau C++ compiler. The problem is that the template class' member
function declarations and definitions are in a seperate file. They must not.
In Visual Studio 6, 7 and 7.1, the template definitions must be in the same
file as the declarations, and this whole package must be completely visible
in every compilation unit where this template is needed to be instantated.

In english, it means that the "my.cpp" file must be removed, and the
 
K

Kefik

Thanks for replies, yesterday I spent half day trying to figure out
what's wrong, if many compilers don't accept that so I have to do it
other way, I nevermind :) thanks again.
 
A

Antti Keskinen

Hi !

Templates are a very powerful feature in C++ language. Learn to use them
properly and learn them well. The STL, ATL and WTL are full of templates,
and each of these libraries sees use in the professional field. Templates
are useful when you need to write wide-scale support for a routine and wish
to save time by specifying only special cases in which the routine looks
different (template specialization).

So, the way I feel about it, use templates. But be extremely careful when
writing them. They are prone to errors, and the current compilers get
sometimes very confused on where the real error is, if there is one. So, use
them whenever they are appropriate, but make total syntax checking by hand,
constantly keeping in mind "What does this REALLY mean, code-wise ?". Then
you'll be succesfull.

-Antti Keskinen


Kefik said:
Hi, well that's interesting, I've found templates fascinating, but
now, I don't know what to think about them, do you think it's better
not to use them at all?
Antti Keskinenwrote: Hi !

This code - with these precise files - will, as far as I know, compile only
with Comeau C++ compiler. The problem is that the template class' member
function declarations and definitions are in a seperate file. They must not.
In Visual Studio 6, 7 and 7.1, the template definitions must be in the same
file as the declarations, and this whole package must be completely visible
in every compilation unit where this template is needed to be instantated.

In english, it means that the "my.cpp" file must be removed, and the
 
G

Greg Comeau

This code - with these precise files - will, as far as I know,
compile only with Comeau C++ compiler. The problem is that the
template class' member function declarations and definitions
are in a seperate file. They must not. In Visual Studio 6, 7
and 7.1, the template definitions must be in the same file
as the declarations, and this whole package must be completely
visible in every compilation unit where this template is needed
to be instantated.

In english, it means that the "my.cpp" file must be removed
and the template class' constructor and destructor definition
code must be moved to "my.h", either underneath the template
declaration, or as part of it. Then the "main.cpp" must include
the "my.h" file. After these changes, it will work.

If you use the Comeau C++ compiler, you must use the 'export'
keyword with the templates.

Yup. Here's one overview:
http://www.comeaucomputing.com/techtalk/templates/#whylinkerror

Currently, this compiler is the only one that recognizes this
keyword and treats it as per C++ Standard.
Correct.

There are reasons why Visual C++
compiler doesn't support it, and probably never will. It's not
because the compiler was buggy: it is because supporting the
keyword doesn't have as long-range benefits as the users expect it to.

At least that's what people say they say, which is not the
same as them saying it.
For example, even with the
keyword, if you build a template library, you must still provide
the definitions of each template that is going to be instantated.

Of course. After all the compiler isn't going to write the
definition for you, so it must be provided somewhere.

The standard
ideology of ".lib, DLL and a header" doesn't work with templates. It just
does not. Not even with Comeau C++.

Well, we don't officially support "Windows programming",
though that's going to _begin_ changing with the release
with its support of the --gui command line option, so saying that
is at least a bit of a red herring argument.

In any event, if you're suggesting folks to abandon templates,
I think that's a bad suggestion.
 
G

Greg Comeau

Hi, well that's interesting, I've found templates fascinating, but
now, I don't know what to think about them, do you think it's better
not to use them at all?

Of course templates are fascinating, and then some. And so
of course they should be used... _when appropriate_.
Also of course, as with all features, leanring the nooks
and crannies, limitations, etc, is part of the process.
 
A

Antti Keskinen

Greg Comeau said:
Well, we don't officially support "Windows programming",
though that's going to _begin_ changing with the release
with its support of the --gui command line option, so saying that
is at least a bit of a red herring argument.

Do you mean that Comeau C++ compiler will be able - at some point - to
provide a situation, in which the implementation code of a template was
stacked into a DLL, and the end user was only provided with the template
header and a static link library file, and the compiler would be able to
look for template instantation calls inside the DLL, and generate necessary
code as per end user's compilation units require ?

The ideology I referred to is the standard procedure in which people like to
distribute their components: the end user can use the component and know
much of it's general structure through the header file, but cannot crack
inside the actual code to see how it was implemented and how it works
without the source files of the dynamic library. I believe this is a
standard approach on any commercial component, not including open-source
ones.
In any event, if you're suggesting folks to abandon templates,
I think that's a bad suggestion.

Not at all. Templates are a very useful feature, I wouldn't trade them off
so easily. That's one of the reasons I've sticked to C++ instead of Java,
PHP or other 'flexible use languages'. You've misunderstood me there :)

-Antti Keskinen
 
G

Greg Comeau

Do you mean that Comeau C++ compiler will be able - at some point - to
provide a situation, in which the implementation code of a template was
stacked into a DLL, and the end user was only provided with the template
header and a static link library file, and the compiler would be able to
look for template instantation calls inside the DLL, and generate necessary
code as per end user's compilation units require ?

The ideology I referred to is the standard procedure in which people like
to distribute their components: the end user can use the component and know
much of it's general structure through the header file, but cannot crack
inside the actual code to see how it was implemented and how it works
without the source files of the dynamic library. I believe this is a
standard approach on any commercial component, not including open-source
ones.

We don't support Windows programming, but will begin doing so
at some level shortly. As with every compiler, I don't know
where things are headed, but I certain hope implementations
continue to get smarter. The standard leaves wiggle room,
and perhaps it can provide even more wiggle, etc. All I'm saying
is that either way it remains to be seen.
Not at all. Templates are a very useful feature, I wouldn't trade
them off so easily. That's one of the reasons I've sticked to C++
instead of Java, PHP or other 'flexible use languages'.

Great.
 

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

Top