unresolved external when using templates

  • Thread starter Shailesh Humbad
  • Start date
S

Shailesh Humbad

I am trying to define some template classes for the first time. But I
am getting the following error when I try to use the template class:

TestTemplatesConsoleApp error LNK2019: unresolved external symbol
"public: __thiscall my<int>::my<int>(void)" (??0?$my@H@@QAE@XZ)
referenced in function _main

When I move the class definition from my.cpp to test.cpp, the error
goes away. What am I doing wrong? Code is below:

--------------
Test.cpp
--------------
#include "my.h"
int _tmain(int argc, _TCHAR* argv[])
{
class my<int> pMy;
// The line below works fine.
// class my2 pMy2;
}
----------
my.h
----------

template<class DE>
class my {
public:
my();
DE testfunc();
private:
int myint;
};

class my2 {
public:
int myint;
my2();
};

---------------
my.cpp
---------------
#include "my.h"

template<class DE>
my<DE>::my()
{
this->myint = 0;
}

my2::my2() {
this->myint = 0;
}
 
S

Sharad Kala

Shailesh Humbad said:
I am trying to define some template classes for the first time. But I
am getting the following error when I try to use the template class:

TestTemplatesConsoleApp error LNK2019: unresolved external symbol
"public: __thiscall my<int>::my<int>(void)" (??0?$my@H@@QAE@XZ)
referenced in function _main

When I move the class definition from my.cpp to test.cpp, the error
goes away. What am I doing wrong? Code is below:

This is perhaps one of the most frequent FAQ :)
http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.13

Point is that the compiler must see the template definition at the point of
template instantiation (unless you use export keyword and a supporting
compiler).

-Sharad
 
S

Shailesh Humbad

Sharad said:
This is perhaps one of the most frequent FAQ :)
http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.13

Point is that the compiler must see the template definition at the point of
template instantiation (unless you use export keyword and a supporting
compiler).

-Sharad

Thanks, I got it now. The FAQ does a good job explaining. I would
never have found the answer through Google. The book I have says, "In
general, it is the implementation's job - _not_ the programmer's - to
ensure that versions of a template function are generated for each set
of template arguments used." (Stroustrup The C++ Programming
Languate). So, I assumed it was automatic.
 
B

Bhanu Ghantasala

And Bruce Eckel in his 'Thinking in C++' recommends the template
definition to be kept in along with declaration , though it violates the
normal header file rule.

Something you'd want to check out after getting an idea from this faq.
 
S

Shailesh Humbad

Bhanu said:
And Bruce Eckel in his 'Thinking in C++' recommends the template
definition to be kept in along with declaration , though it violates the
normal header file rule.

Something you'd want to check out after getting an idea from this faq.

That's a good idea. I did that in my code.

Now, I have another problem. I have two friend template classes that
are dependent on each other. In particular, a function in one class
(my2) creates an instance of the second class (my) and returns a
pointer to it. The specialization of the returned class (my) should
match the specialization of the original (my2). But when I try to
write the code, I get many compiler errors at the definition of
myfunc(). The syntax is wrong, and probably my thinking is wrong too.
Can you C++ gurus help with this? Code is below:


----------------
my.cpp
-------------------
template<class DE>
class my {
public:
my();
int myint;
};

template<class DE>
class my2 {
public:
my2();
class my<DE> * myfunc(void);
int my2int;
};

template<class DE>
my<DE>::my()
{
this->myint = 0;
}

template<class DE>
my2<DE>::my2()
{
this->my2int = 0;
}

template<class DE>
class my<DE> *
my2<DE>::myfunc(void)
{
return NULL;
}

-------------------
main.cpp
-------------------
#include "my.cpp"

int _tmain(int argc, _TCHAR* argv[])
{
class my<int> pMy;
class my2<int> pMy2;
return 0;
}
 
S

Sharad Kala

Shailesh Humbad said:
Bhanu Ghantasala wrote:
[snip]
Replace all class my<..> /class my2<...> with my<..>/my2<...> and and it should
be fine.

-Sharad
 
S

Shailesh Humbad

Sharad said:
Replace all class my<..> /class my2<...> with my<..>/my2<...> and and it should
be fine.

-Sharad

Yep, that worked. Why? I don't like this. This means the "class"
keyword is sometimes synonymous with "typename", sometimes it is
optional, sometimes it is required, and sometimes it must be excluded.
This is enough to remind me of that wicked wizard language called Perl.
 
S

Sharad Kala

Shailesh Humbad said:
Yep, that worked. Why?

Because what you were doing was syntax error.
I don't like this. This means the "class"
keyword is sometimes synonymous with "typename", sometimes it is
optional, sometimes it is required, and sometimes it must be excluded.

Not quite. It is well defined when one needs a typename and it is no longer
optional IMO.
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top