We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

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

Medium Priority
727 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);
}
      
Comment
Watch Question

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.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
jkr
CERTIFIED EXPERT
Top Expert 2012
Commented:
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.
>>> 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.

Oh, I was late ;-)
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.
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.
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

Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.