This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 7 years ago.
I am trying to figure out how to use classes with class template and I get these errors:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall AdtBag::AdtBag(void)" (??0?$AdtBag#H##QAE#XZ) referenced in function _main C:\Users\User\Documents\Visual Studio 2013\Projects\ADTBagAddition\ADTBagAddition\Source.obj ADTBagAddition
Error 2 error LNK2019: unresolved external symbol "public: __thiscall AdtBag::~AdtBag(void)" (??1?$AdtBag#H##QAE#XZ) referenced in function _main C:\Users\User\Documents\Visual Studio 2013\Projects\ADTBagAddition\ADTBagAddition\Source.obj ADTBagAddition
Error 3 error LNK2019: unresolved external symbol "public: void __thiscall AdtBag::store_in_bag(int)" (?store_in_bag#?$AdtBag#H##QAEXH#Z) referenced in function _main C:\Users\User\Documents\Visual Studio 2013\Projects\ADTBagAddition\ADTBagAddition\Source.obj ADTBagAddition
Error 4 error LNK2019: unresolved external symbol "public: int __thiscall AdtBag::whats_in_bag(void)" (?whats_in_bag#?$AdtBag#H##QAEHXZ) referenced in function _main C:\Users\User\Documents\Visual Studio 2013\Projects\ADTBagAddition\ADTBagAddition\Source.obj ADTBagAddition
Error 5 error LNK1120: 4 unresolved externals C:\Users\User\Documents\Visual Studio 2013\Projects\ADTBagAddition\Debug\ADTBagAddition.exe ADTBagAddition
Here is my code:
source.cpp
#include <iostream>
#include "AdtBag.h"
using namespace std;
int main () {
AdtBag<int> BagInt;
int a = 78;
cout << "Int Bag Contains: " << endl;
BagInt.store_in_bag ( a );
cout << BagInt.whats_in_bag () << endl;
return 0;
}
AdtBag.h
#ifndef __ADTBAG__
#define __ADTBAG__
template<class ItemType>
class AdtBag {
private:
ItemType in_bag;
public:
AdtBag<ItemType> ();
~AdtBag<ItemType> ();
void store_in_bag ( ItemType into_bag );
ItemType whats_in_bag ();
};
#endif
AdtBag.cpp
#include "AdtBag.h"
template <class ItemType>
AdtBag<ItemType>::AdtBag () {
}
template <class ItemType>
AdtBag<ItemType>::~AdtBag () {
}
template<class ItemType>
void AdtBag<ItemType>::store_in_bag ( ItemType into_bag ) {
in_bag = into_bag;
}
template<class ItemType>
ItemType AdtBag<ItemType>::whats_in_bag () {
return in_bag;
}
Why is this producing the error messages? I'm using Visual Studio 2013 if that matters. I thought I did everything correctly, but I guess not. Any suggestions?
Loosely speaking, all template class code must be in the header.
Essentially, this is because template code is only compiled when a template is instantiated for some type.
Related
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 5 years ago.
i'm just writing an array class as practice in Microsoft Visual Studio 2010 but i'm getting some annoying errors. here they are:
1>test.obj : error LNK2019: unresolved external symbol "public: __thiscall arrays<int>::~arrays<int>(void)" (??1?$arrays#H##QAE#XZ) referenced in function _wmain
1>test.obj : error LNK2019: unresolved external symbol "public: int & __thiscall arrays<int>::operator[](int)" (??A?$arrays#H##QAEAAHH#Z) referenced in function _wmain
1>test.obj : error LNK2019: unresolved external symbol "public: bool __thiscall arrays<int>::operator==(class arrays<int> const &)const " (??8?$arrays#H##QBE_NABV0##Z) referenced in function _wmain
1>test.obj : error LNK2019: unresolved external symbol "public: int const & __thiscall arrays<int>::operator=(class arrays<int> const &)" (??4?$arrays#H##QAEABHABV0##Z) referenced in function _wmain
1>test.obj : error LNK2019: unresolved external symbol "public: __thiscall arrays<int>::arrays<int>(class arrays<int> const &)" (??0?$arrays#H##QAE#ABV0##Z) referenced in function _wmain
1>test.obj : error LNK2019: unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class arrays<int> const &)" (??5#YAAAV?$basic_istream#DU?$char_traits#D#std###std##AAV01#ABV?$arrays#H###Z) referenced in function _wmain
1>test.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class arrays<int> const &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#ABV?$arrays#H###Z) referenced in function _wmain
1>test.obj : error LNK2019: unresolved external symbol "public: int __thiscall arrays<int>::getsize(void)const " (?getsize#?$arrays#H##QBEHXZ) referenced in function _wmain
1>test.obj : error LNK2019: unresolved external symbol "public: __thiscall arrays<int>::arrays<int>(int)" (??0?$arrays#H##QAE#H#Z) referenced in function _wmain
1>c:\users\bm\documents\visual studio 2010\Projects\arrays\Debug\arrays.exe : fatal error LNK1120: 9 unresolved externals
how can I fix them?
here is my code:
arrays.h
#ifndef ARRAYS_H
#define ARRAYS_H
#include <iostream>
using namespace std;
template <typename T>
class arrays{
friend ostream &operator<<(ostream &output, const arrays &a);
friend istream &operator>>(istream &input, const arrays &a);
public:
arrays(int = 10);
arrays(const arrays &);
~arrays();
int getsize() const;
const T &operator=(const arrays &);
bool operator==(const arrays &) const;
bool operator!=(const arrays &right) const{
return !((*this)==right);
}
T &operator[](int);
T operator[](int) const;
private:
int size;
T *ptr;
};
#endif
arrays.cpp
#include "stdafx.h"
#include <iostream>
#include "arrays.h"
#include <cstdlib>
using namespace std;
template <typename T>
arrays<T>::arrays(int mysize){
size = mysize;
ptr = new(int[size]);
for(int i = 0; i< size; i++)
ptr[i] = 0;
}
template <typename T>
arrays<T>::arrays(const arrays<T> &myarray){
size = myarray.size;
ptr = new(int[size]);
for(int i = 0; i< size; i++){
ptr[i] = myarray.ptr[i];
}
}
template <typename T>
arrays<T>::~arrays(){
delete [] ptr;
}
template <typename T>
int arrays<T>::getsize() const {
return size;
}
template <typename T>
const T &arrays<T>::operator=(const arrays<T> &right){
if ( &right != this){
if(size != right.size){
delete [] ptr;
size= right.size;
ptr = new(int[size]);
}
for(int i =0; i < size; i++)
ptr[i] = right.ptr[i];
}
return *this;
}
template <typename T>
bool arrays<T>::operator==(const arrays<T> &right) const{
if(right.size != size)
return false;
for(int i = 0; i<size; i++)
if(ptr[i] != right.ptr[i])
return false;
return true;
}
template <typename T>
T &arrays<T>::operator[](int subscript) {
if(subscript < 0 || subscript >= size){
cout << "error: subscript out of range";
}
return ptr[subscript];
}
template <typename T>
T arrays<T>::operator[](int subscript) const {
if(subscript < 0 || subscript >= size){
cout << "error: subscript out of range";
exit(1);
}
return ptr[subscript];
}
template <typename T>
istream &operator>>(istream &input, const arrays<T> &a){
for(int i = 0; i< a.size; i++)
input >> a.ptr[i];
return input;
}
template <typename T>
ostream &operator<<(ostream &output, arrays<T> &a){
for(int i= 0; i<a.size;i++)
output << a.ptr[i];
return output;
}
any help would be appreciated.
Implementation code for a template class must live in the header, not in the .cpp file. This is required so that other code that use your template class can "instanciate" it's code based on the template parameter.
So just move all your code from your .cpp to your .h and you're good to go.
This question already has answers here:
Why do I get "unresolved external symbol" errors when using templates? [duplicate]
(3 answers)
Closed 7 years ago.
I am trying to implement a few classes but i got the following error when compiling the codes. I have tried to removed all the redundant codes but none of them helps. I have no idea what went wrong.
Here is the error i get when compile the code:
Severity Code Description Project File Line
Error LNK2019 unresolved external symbol "public: __thiscall FullArray<int>::FullArray<int>(unsigned int)" (??0?$FullArray#H##QAE#I#Z) referenced in function _wmain FinancialDerivatives C:\Users\Jeremy Nguyen\Documents\Visual Studio 2015\Projects\FinancialDerivatives\FinancialDerivatives\FinancialDerivatives.obj 1
Error LNK1120 2 unresolved externals FinancialDerivatives C:\Users\Jeremy Nguyen\Documents\Visual Studio 2015\Projects\FinancialDerivatives\Debug\FinancialDerivatives.exe 1
Error LNK2019 unresolved external symbol "public: virtual __thiscall FullArray<int>::~FullArray<int>(void)" (??1?$FullArray#H##UAE#XZ) referenced in function _wmain FinancialDerivatives C:\Users\Jeremy Nguyen\Documents\Visual Studio 2015\Projects\FinancialDerivatives\FinancialDerivatives\FinancialDerivatives.obj 1
FullArray.h file:
#pragma once
#include <vector>
template <class V>
class FullArray
{
private:
std::vector<V> m_vector; // Use STL vector class for storage
public:
// Constructors & destructor
FullArray();
FullArray(size_t size);
FullArray(const FullArray<V>& source);
FullArray<V>& operator = (const FullArray<V>& source);
virtual ~FullArray();
};
FullArray.cpp file:
#include "stdafx.h"
#include "FullArray.h"
template<class V>
FullArray<V>::FullArray()
{
m_vector = std::vector<V>(1); // vector object with 1 element
}
template<class V>
FullArray<V>::FullArray(size_t size)
{
m_vector = std::vector<V>(size);
}
template<class V>
FullArray<V>::FullArray(const FullArray<V>& source)
{
m_vector = source.m_vector;
}
template<class V>
FullArray<V>& FullArray<V>::operator=(const FullArray<V>& source)
{
// Exit if same object
if (this == &source) return *this;
// Call base class constructor
//ArrayStructure<V>::operator = (source);
// Copy the embedded vector
m_vector = source.m_vector;
return *this;
}
template<class V>
FullArray<V>::~FullArray()
{
}
main file:
#include "stdafx.h"
#include "FullArray.h"
int _tmain(int argc, _TCHAR* argv[])
{
FullArray<int> tmp(5);
return 0;
}
If you compile templates, the source needs to be available at any place where they are used, so include your .cpp file at the bottom of the .h file, or include the .cpp file instead of the .h file.
#include "stdafx.h" //In order to use Visual C++
#include <iostream>
#include <Loki\SmallObj.h> //The header file to manage
// smalls objects allocator
class MySmallObj : public Loki::SmallObjAllocator //inherit from the base
//class SmallObjAllocator
{
public:
MySmallObj():SmallObjAllocator(sizeof(char), sizeof(long),0){};
};
int _tmain(int argc, _TCHAR* argv[])
{
MySmallObj * premier = new MySmallObj; //declaring my object derived from smallobjallcator
char * myChar = static_cast<char*>( premier->Allocate(1, true)); //calling allocate from my object and conveting the void pointer to char*
premier.Deallocate(myChar, 1);
return 0;
}
The loki library uses essentially generic programming in c++
I have got the code up there using Small object allocator of memory(Loki::SmallObjAllocator)
I m using visual c++ 2010
I get those errors:
> MyLoki.cpp
1>MyLoki.obj : error LNK2019: unresolved external symbol "public: void __thiscall Loki::SmallObjAllocator::Deallocate(void *,unsigned int)" (?Deallocate#SmallObjAllocator#Loki##QAEXPAXI#Z) referenced in function _wmain
1>MyLoki.obj : error LNK2019: unresolved external symbol "public: void * __thiscall Loki::SmallObjAllocator::Allocate(unsigned int,bool)" (?Allocate#SmallObjAllocator#Loki##QAEPAXI_N#Z) referenced in function _wmain
1>MyLoki.obj : error LNK2019: unresolved external symbol "protected: __thiscall Loki::SmallObjAllocator::SmallObjAllocator(unsigned int,unsigned int,unsigned int)" (??0SmallObjAllocator#Loki##IAE#III#Z) referenced in function "public: __thiscall MySmallObj::MySmallObj(void)" (??0MySmallObj##QAE#XZ)
I have founded an answer to my first question.
#include "stdafx.h" //In order to use Visual C++
#include <iostream>
#include <Loki\SmallObj.h> //The header file to manage
// smalls objects allocator
class MySmallObj : public Loki::SmallObjAllocator //inherit from the base
//class SmallObjAllocator
{
public:
MySmallObj():SmallObjAllocator(sizeof(char), sizeof(long),1){}; //the chunkSize < maxObjsize
};
int _tmain(int argc, _TCHAR* argv[])
{
MySmallObj * premier = new MySmallObj; //declaring my object derived from smallobjallcator
char * myChar = static_cast<char*>( premier->Allocate(1, true)); //calling allocate from my object and conveting the void pointer to char*
premier->Deallocate(myChar, 1);
return 0;
}
the errors of multiple
unresolved external symbol
are because of SmallObj.cpp , of Loki that was not included to the project
for example of Loki::SmallObjAllocator, Loki::SmallObject here
In order to test leveldb, I tried to reproduce the leveldb's example on VS 2008.
#include <assert.h>
#include "leveldb/db.h"
int main()
{
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options,"D:\dev\tools\tmp",&db);
}
I have included leveldb/include directory and linked libleveldb.lib.
Result :
error LNK2019: unresolved external symbol "public: static class
leveldb::Status __cdecl leveldb::DB::Open(struct leveldb::Options
const &,class std::basic_string,class std::allocator > const &,class
leveldb::DB * *)"
(?Open#DB#leveldb##SA?AVStatus#2#ABUOptions#2#ABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##PAPAV12##Z)
referenced in function _main
error LNK2019: unresolved external symbol public: __thiscall leveldb::Options::Options(void)"
(??0Options#leveldb##QAE#XZ) referenced in function _main
Does anyone know how to fix this ?
Solution :
Use levelDb-portable from zhangyafreikimi
PacketBuilder is a little Class which allow to write into a char* array. The Append Functions:
template <class T>
void PacketBuilder::Append(const T value)
{
memcpy((&m_Buffer) + m_Index, (const void*) &value, sizeof(T));
m_Index += sizeof(T);
}
Compiling without errors. If I call Append and use T as unsigned short (WORD). It works great. If I use T as unsigned char. I get an Linker Error.
m_Builder.Append<unsigned char>(0x01); // Error: LNK1120
m_Builder.Append<unsigned short>(0x0001); // Works
Error from VS2010 (sry i got german vs2010):
error LNK2019: Verweis auf nicht
aufgelöstes externes Symbol ""public:
void __thiscall
PacketBuilder::Append(unsigned char)"
(??$Append#E#PacketBuilder##QAEXE#Z)"
in Funktion ""public: void __thiscall
Client::DoHandshake(void)"
(?DoHandshake#Client##QAEXXZ)".
1>C:\XXX\C++\SilkroadEmu\Debug\LoginServer.exe
: fatal error LNK1120: 1 nicht
aufgelöste externe Verweise.
Translated to English:
error LNK2019: Unresolved external
symbol ""public: void __thiscall
PacketBuilder::Append(unsigned char)"
(??$Append#E#PacketBuilder##QAEXE#Z)"
in Function ""public: void __thiscall
Client::DoHandshake(void)"
(?DoHandshake#Client##QAEXXZ)".
1>C:\XXX\C++\SilkroadEmu\Debug\LoginServer.exe
: fatal error LNK1120: 1 unsresolved
external symbol.
Put the method definition in the header (hpp file), not in the implementation (cpp) file.
Your PacketBuilder is not a class template, as far as I can see. PacketBuilder::Append is however a template method, which requires that it's definition must be visible at any point of instantiation of this method. The only really safe way to assure this is to put the complete definition of this method template into the header file:
class PacketBuilder {
// declarations of non-template members
public:
template <class T>
void Append(const T value)
{
memcpy((&m_Buffer) + m_Index, (const void*) &value, sizeof(T));
m_Index += sizeof(T);
}
};