0

I know this problem is well known, but none of the solutions work for me. I know a popular cause of this error is the compiler can't find the definition of a function in any of the source files, but I have defined the function them.

I am using Visual studio 2015 community.

Form.h

#pragma once
template<typename T>
class Form
{
public:
    void GenerateForm(T i);
};

Form.cpp

#include "stdafx.h"
#include "Form.h"

template<typename T>
void Form<T>::GenerateForm(T i)
{
    std::cout << i << endl;
}

Main.cpp

#include "stdafx.h"
#include "Form.h"

int main()
{
    Form<int> f;
    f.GenerateForm(12);
    return 0;
}

Error:

PrimeForm.obj : error LNK2019: unresolved external symbol "public: void __thiscall Formula<double>::GenerateForm(int)" (?GenerateForm@?$Formula@N@@QAEXH@Z) referenced in function _main
C:\Users\John\Dropbox\Visual Studio 2015\PrimeForm\Debug\PrimeForm.exe : fatal error LNK1120: 1 unresolved externals
Schugz
  • 25
  • 4

1 Answers1

0

When you try to compile form.cpp the compiler doesn't know what type T will be. Therefore it won't be able to compile this as an object file to be linked with your compiled main.cpp object file.

You'll need to include all of the declarations and definitions of a templated class to the files that need it (in this case your main.cpp file).

This can be simply done as follows:

Form.h

 #pragma once
 template<typename T>
 class Form
 {
 public:
     void GenerateForm(T i);
 };

 #include "Form.template"  /* Note include Form.template here */

Form.template

#include "stdafx.h"
/* Don't include form.h in this file */

template<typename T>
void Form<T>::GenerateForm(T i)
{
    std::cout << i << std::endl;
}

main.cpp

#include "stdafx.h"
#include "Form.h"  /* including Form.h will include Form.template as well */

int main()
{
    Form<int> f;        /* Compiler now knows to instantiate a Form class with type Int as the template parameter */
    f.GenerateForm(12); 
    return 0;
}

Note the main difference is that you don't include "Form.h" in Form.template but include "Form.template" at the bottom of Form.h

It is better practice to use the ".template" file ending for templated class implementation files.

Timothy Murphy
  • 1,322
  • 8
  • 16
  • Including cpp files is very,very bad form. – user4581301 Aug 05 '15 at 01:48
  • You're right. Although sometimes you do want to separate the template class declaration and definitions into two files. I've changed the Form.cpp to use .template file ending. – Timothy Murphy Aug 05 '15 at 01:53
  • Better, but why have the extra file at all? The rationale for separating the implementation from the class is lost as soon as you have to recompile the client for code changes to the function, so there is nothing to be lost and clarity to be gained by defining the GenerateForm function inside the class. The other solution, and sometimes a good one to limit code size, is to add `template class Form;` to the bottom of Form.cpp. This creates one and only one `int` version of Form for all users. Overkill for this case. – user4581301 Aug 05 '15 at 02:01
  • I would agree, In this case there doesn't seem to be any need of splitting the files apart. In larger projects where you have particularly large classes and a number of non-member functions using the templated class, it may make sense to split the code into two files. – Timothy Murphy Aug 05 '15 at 02:41