This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 7 years ago.
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
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.
Related
I have followed some instructions to construct Visual studio code C/C++ compile and debug environment. But MSVC compiler can only compile the selected cpp file, so the included .h file associated the cpp file can not compiled. then the terminal shows
*
main.obj : LNK2019 error: reference to an unresolved external
character "int __cdecl func(void)" (?func##YAHXZ) in the main
function.C:\TESTmsvc\main.exe : fatal error LNK1120: unresolved
external elements: 1
The code as below:
the a.h file
int func();
the a.cpp file
#include <iostream>
#include "a.h"
using namespace std;
int func(){
return 111;
}
the main.cpp file
#include "a.h"
using namespace std;
int main()
{
int b = func();
cout << b << endl;
}
This is my first time having separate files and first time writing a header file, however I keep getting the same error I can't fix. Here are the files:
//main.cpp
#include <iostream>
#include "Bike.h"
/*
class Bike{
public:
int tyreDiameter;
int getTyreDi(){
return tyreDiameter;
}
}; */
int main(){
Bike b;
b.tyreDiameter = 50;
std::cout << b.getTyreDi();
while (1){
continue;
}
return 0;
}
//Bike.cpp
class Bike{
public:
int tyreDiameter;
int getTyreDi(void){
return tyreDiameter;
}
};
//Bike.h
#ifndef BIKE_H
#define BIKE_H
class Bike{
public:
int tyreDiameter;
int getTyreDi(void);
};
#endif
Now if I have only one file and use the class that is commented out in main.cpp everything works fine. But as soon as I try to separate the Bike class into another cpp file I get this error:
Error 1 error LNK2019: unresolved external symbol "public: int
__thiscall Bike::getTyreDi(void)" (?getTyreDi#Bike##QAEHXZ)
Error 2 error LNK1120: 1 unresolved externals
I am using Microsoft Visual Studio 2013.
Any help would be much appreciated
Why are you defining class Bike twice? in the cpp and in the h, the correct way would be this:
header
//Bike.h
#ifndef BIKE_H
#define BIKE_H
class Bike{
public:
int tyreDiameter;
int getTyreDi(void);
};
#endif
cpp
//Bike.cpp
#include "Bike.h"
int Bike::getTyreDi(void)
{
//implementation like return tyreDiameter;
}
My c++ program fails with below reasons:
Error 1 error LNK2005: "public: void __thiscall dataHolder::addData(int)" (?addData#dataHolder##QAEXH#Z) already defined in Source.obj
Error 2 error LNK2005: "public: void __thiscall dataHolder::findUnique(void)" (?findUnique#dataHolder##QAEXXZ) already defined in Source.obj
Error 3 error LNK2005: "public: void __thiscall dataHolder::printData(void)" (?printData#dataHolder##QAEXXZ) already defined in Source.obj
Error 4 error LNK1169: one or more multiply defined symbols found
However, when I moved all definitions in once source c++ file, it worked fine.
Below is my source code:
source.cpp file:
#include "dataClass.h"
void main(){
dataHolder v1;
for(int i=1;i<=10;i++)
v1.addData(i);
for(int i=1;i<=5;i++)
v1.addData(i);
v1.printData();
v1.findUnique();
}
dataClass.h file:
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <vector>
#include <map>
using namespace std;
class dataHolder{
public:
void printData();
void addData(int data);
void findUnique();
int uniqueData();
private:
vector<int> dataVector;
};
void dataHolder::addData(int val){
dataVector.push_back(val);
};
void dataHolder::printData(){
vector<int>::iterator vIt;
for(vIt=dataVector.begin();vIt<dataVector.end();vIt++){
cout<< *vIt<<endl;
};
};
void dataHolder::findUnique(){
map<int ,int> dataMap;
vector<int>::iterator vIt;
map<int ,int>::iterator mIt;
for(vIt=dataVector.begin();vIt<dataVector.end();vIt++){
if(dataMap.find(*vIt)==dataMap.end())
dataMap[*vIt]=1;
else
dataMap[*vIt] = dataMap[*vIt]+1;
};
for(mIt=dataMap.begin();mIt != dataMap.end();mIt++){
if(mIt -> second == 1)
cout<<mIt->first<<" is Unique"<<endl;
};
};
please guide for the issue.
The problem is that you define the dataHolder member functions in the header file. That means that every source file including your header file will have the definition of those member functions.
You can do that, but then you have to mark them as inline, or possibly static.
What you should do is make another source file, which contains the member function definitions, and include that source file in your project so it's compiled and linked with.
Move your implementations for the class methods into a cpp file (not the header file). This way, they don't get included multiple times.
You just should move class members implementation to .cpp file. For example dataClass.cpp:
#include "dataClass.h"
void dataHolder::addData(int val){
dataVector.push_back(val);
};
void dataHolder::printData(){
vector<int>::iterator vIt;
for(vIt=dataVector.begin();vIt<dataVector.end();vIt++){
cout<< *vIt<<endl;
};
};
void dataHolder::findUnique(){
map<int ,int> dataMap;
vector<int>::iterator vIt;
map<int ,int>::iterator mIt;
for(vIt=dataVector.begin();vIt<dataVector.end();vIt++){
if(dataMap.find(*vIt)==dataMap.end())
dataMap[*vIt]=1;
else
dataMap[*vIt] = dataMap[*vIt]+1;
};
for(mIt=dataMap.begin();mIt != dataMap.end();mIt++){
if(mIt -> second == 1)
cout<<mIt->first<<" is Unique"<<endl;
};
};
You could also use header guards to ensure that your header file is loaded only once.
#ifndef _DATA_CLASS_H_
#define _DATA_CLASS_H_
#include <...>
class dataHolder {
...
}
/* Function Definitions */
#endif /* _DATA_CLASS_H_ */
See this question: C++ - header guards
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 years ago.
When trying to compile my program this error shows up:
Error 1 error LNK2001: unresolved external symbol "public: static class sf::Texture TextureManager::texture" (?texture#TextureManager##2VTexture#sf##A)
This is my code:
main.cpp:
int main()
{
TextureManager::Initialize();
}
TextureManager.h:
#include <SFML\Graphics.hpp>
using namespace sf;
class TextureManager
{
public:
static Texture texture;
public:
static void Initialize();
};
TextureManager.cpp:
#include <SFML\Graphics.hpp>
#include <iostream>
#include "TextureManager.h"
using namespace sf;
void TextureManager::Initialize()
{
if(!texture.loadFromFile("Textures\\Blocks\\Texture.png"))
{
std::cout << "Error!";
}
else
{
std::cout << "Sucess!";
}
}
I've tried searching for any solutions (including this site) but have not found any.
When you have a static member in C++, you should define it in your .cpp :
static Texture Texture::texture;
This is because static members must be defined in exactly one translation unit, in order to not violate the One-Definition Rule.
You can do it at the top of your TextureManager.cpp:
#include <SFML\Graphics.hpp>
#include <iostream>
#include "TextureManager.h"
using namespace sf;
static Texture Texture::texture; // <-
void TextureManager::Initialize()
{
}
I am implementing a simple Linked List, but I keep getting the LNK2019 error, I simplified my code to the minimum to track the problem,but I keep getting it. I am using Visual Studio 2010. My header file is:
#ifndef __TSLinkedList__H__
#define __TSLinkedList__H__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "LinkedNode.h"
template <class T>
class LinkedList
{
public:
LinkedList(void);
~LinkedList(void);
protected:
LinkedNode<T> * head;
};
The implementation file is:
#include "StdAfx.h"
#include "LinkedList.h"
template <class T>
LinkedList<T>::LinkedList(void)
{
head = NULL;
}
template <class T>
LinkedList<T>::~LinkedList(void)
{
}
the main function is:
#include "stdafx.h"
#include "stdlib.h"
#include "LinkedList.h"
int _tmain(int argc, _TCHAR* argv[])
{
LinkedList<int> mList;
system("PAUSE");
return 0;
}
and I am getting this error:
Error 1 error LNK2019: sÃmbolo externo "public: __thiscall LinkedList::~LinkedList(void)" (??1?$LinkedList#H##QAE#XZ) in function _wmain
I get the same error with the Constructor. The funny thing is that it is pointing to _wmain, and my main function is called _tmain. I already tried to change Subsystem linker from /SUBSYSTEM:WINODWS to /SUBSYSTEM:CONSOLE, but it was already set up as /SUBSYSTEM:CONSOLE. Obviously my implementation does a lot more than this, but I ripped out all of it to track this problem. Help wpuld be apreciated, this is driving me nuts. I am new to C++.
Move the function implementations to the header file.
In order to generate code for the specialization, the compiler must have the definitions of the functions available to each translation unit.
#ifndef __TSLinkedList__H__
#define __TSLinkedList__H__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "LinkedNode.h"
template <class T>
class LinkedList
{
public:
LinkedList(void);
~LinkedList(void);
protected:
LinkedNode<T> * head;
};
template <class T>
LinkedList<T>::LinkedList(void)
{
head = NULL;
}
template <class T>
LinkedList<T>::~LinkedList(void)
{
}
#endif
The compiler doesn't compile your template class member definitions, since they are not included in any compilation unit.
However, it does see that some members are used, so it will generate 'undefined' symbols for these.
Then comes the linker, trying to match the undefined symbols to some symbols defined in one of the compiled object files.
But, the LinkedList::~LinkedLis() destructor hasn't been compiled, so it's in none of the object files, and that's what the linker complains about.
You can fix this by
including the definition file in the main source file,
or pasting the definitions inside the template header file,
or including the template implementation file from the bottom of the template header file (my favorite)