?
Solved

Visual C++ link error when I try to call a template function defined in another class

Posted on 2009-02-19
7
Medium Priority
?
693 Views
Last Modified: 2013-12-14
My question is regarding my Visual C++ project done on MS Visual Studio 2005:

I have a non-template class with a public template member function.  I have a second class which instantiates an object of the first class and calls the template function of the first class.  Both classes compile without any problems but I get errors during the link phase of the project build (LNK2028: unresolved token and LNK2019: unresolved external symbol).  I've tried including the body/definition of the template function in the header file of the first class but that did not help.  What am I doing wrong?  There's no linkage problems if I convert the template function to a regular non-template function.

Below is an exmaple of what I'm trying to do.

classA.h
--------
class classA
{
     public:
        classA();
        virtual ~classA();

        template <class T>
        double templateFunct(T varA, double varB);
}

===========

classA.cpp
-----

#include "classA.h"

template <class T>
double classA::templateFunct(T varA, double varB)
{
   return varA * varB;
}
      
==================

classB.h
--------
#include "classA.h"

class classB
{
     public:
        classB();
        virtual ~classB();

        double UseClassAFunct();

       classA  m_classAObj;
}

===========

classB.cpp
-----
#include "classB.h"

double classB::UseClassAFunct();
{
     long varA = 2200;
     double varB = 55.76;

    return  m_classAObj.templateFunct(varA, varB);
}
      
0
Comment
Question by:khrispy
7 Comments
 

Accepted Solution

by:
Daramarak earned 600 total points
ID: 23684673
You cannot have the template code in your cpp file. The template code must be visible for all units that includes it.

Move the code into the .h file, and it will be good.
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 400 total points
ID: 23684751
Altrenatively, #include the .cpp file like

classA.h
--------
class classA
{
     public:
        classA();
        virtual ~classA();

        template <class T>
        double templateFunct(T varA, double varB);
}

#include "classA.cpp"

===========

classA.cpp
-----


template <class T>
double classA::templateFunct(T varA, double varB)
{
   return varA * varB;
}
     
==================

Even though what you are doing is valid following the C++ standard, only a few compilers do support that.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 23684783
>>> I've tried including the body/definition of the template function in the header file

Daramarak's explanation is not quite true. You can have a cpp file for template implementation but you have to include that cpp in every source where you use the template.

// x.cpp

#include "mytemplate.h"  

...
void func()
{

     MyTemplate<int> mt;
     mt.dosomething();
}

// include template implementations
#include "mytemplate.cpp"


Of course you also could do that into one header file as Daramarak suggested. But I found it quite convenient to seperate implementation from declaration. Including cpp files may look somewhat strange but you could put the include at the end of your source as I did in my sample or you could have one include file which includes all template cpp.

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 23684797
Oh, I was late ;-)
0
 

Expert Comment

by:Daramarak
ID: 23685111
For my part i use .h files for published information, and .cpp for my codes private parts. Of course you can include a .cpp file (You can also include a .k or .foobar). But it is all a matter of taste. Although some might be confused by seeing an included .cpp file, or take it for granted that the visibility of a .cpp file is only within file scope.
0
 

Expert Comment

by:nikhiledu
ID: 23685253
The template compilation model suggested above is called Inclusion Compilation Model where by the associated template function or class definition must be visible in the same scope as the corresponding template function or class declaration.

There is another compilation model called Separate Compilation Model which supports separate compilation of a template function or class declaration and definition. The C++ keyword export need to prefixed on the template function or class definition placed in a separately compiled .cpp source file. Though many compilers may not support this compilation model including Visual C++ 8.
0
 

Expert Comment

by:Daramarak
ID: 23687765
If your code is exactly as your sample. You have problems with not ending the classes with ;

Also your constructors and destructors has no body, even though they are declared

By fixing this and placing the template code into the header (or making it visible with the other suggestions made above it compiles happily.
-- classA.h
 
class classA
{
public:
  classA() {};
  virtual ~classA() {};
 
  template <class T>
  double templateFunct(T varA, double varB)
  {
    return varA * varB;
  }
};
 
-- classA.cpp
 
#include "classA.h"
 
-- classB.h
 
#include "classA.h"
 
class classB
{
     public:
  classB() {};
  virtual ~classB() {};
 
        double UseClassAFunct();
 
       classA m_classAObj;
};
 
-- classB.cpp
 
 
#include "classb.h"
 
double classB::UseClassAFunct()
{
     long varA = 2200;
     double varB = 55.76;
 
    return  m_classAObj.templateFunct(varA, varB);
}
 
 
int main() {
  classB b;
  return 0 ;
};

Open in new window

0

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question