Class Template Errors - c++

The question asked is very different from the so called duplicate post as I have specific errors and they are just asking why it needs to be in the .h file... I already have it in the header file and am getting the errors below.
Updated the files and I still get the following errors.
1 Unresolved externals (lab12.exe line 1)
unresolved external symbol "public char__thiscall Pair::geetFirst(void)" (?getFirst#?$Pair#D##QAEDXZ) referenced in function_main (lab12.obj line 1)
Pair.h
#pragma once
template <class T>
class Pair
{
private:
T theFirst;
T theSecond;
public:
/*Pair(const T& dataOne, const T& dataTwo);*/
Pair(T a, T b) {
theFirst = a;
theSecond = b;
}
T getFirst();
T getSecond();
};
Pair.cpp
#include "stdafx.h"
#include "Pair.h"
template<class T>
T Pair<T>::getFirst()
{
return theFirst;
}
template<class T>
T Pair<T>::getSecond()
{
return theSecond;
}
Main.cpp
#include "stdafx.h"
#include "Pair.h"
#include <iostream>
using namespace std;
int main()
{
Pair <char> letters('a', 'd');
cout << letters.getFirst();
cout << endl;
system("Pause");
return 0;
}

You should put all code for template class Pair into the header file.
Also, there is no need to separate method declaration from definition in header.
'Pair T::Pair' is wrong because you do not need T here.

Related

Template class does not name a type error, separated definition and declaration for header

I am attempting to create a templated vector class, but upon compilation I am receiving an error of
def.hpp:3:1: error: 'TempVector' does not name a type
I keep referring to reference material and my syntax and handling of the header file declaration and definition (.h and .hpp) seem right to me, but I can not figure out what I am overlooking.
Below is the three files I am working with, thank you.
driver.cpp:
#include <iostream>
#include <string>
#include "dec.h"
using namespace std;
int main() {
TempVector <int> v1;
cout<<"ran successfully"<<endl;
}
dec.h:
#ifndef DEC_H
#define DEC_H
#include <iostream>
#include <utility>
// Declaration of class Vector
template <typename T>
class TempVector {
public:
TempVector ();
private:
T* array;
static const unsigned int spare = 10;
};
#include "def.hpp"
#endif
def.hpp:
template <typename T>
TempVector<T>::TempVector () {
std::cout<<"ran successfully";
}

Template and deque [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 2 years ago.
I'm trying to work with deque and template and I wanted to add others files (func.cpp and func.h) so I can declare all my function in these files and then include func.h in main.cpp but I got an some errors:
1. argument list for variable template "display" is missing in main.cpp
2.'deque': undeclared identifier in func.cpp
3.'d': undeclared identifier in func.cpp
here's the main.cpp:
#include <iostream>
#include <algorithm>
#include <deque>
#include "funcr.h"
using namespace std;
int main()
{
deque <int> d1{ 1,5,3,9 };
d1.push_front(2);
display(d1);
return 0;
}
and here's the func.cpp:
#include <iostream>
#include <deque>
template<typename T>
void display(deque<T> d)
{
for (auto e : d)
std::cout << e << std::endl;
}
and there is the func.h:
#pragma once
template<typename T>
void display(deque<T>d);
can someone help me please?
You must define display in func.h, because templated functions must be implemented in header files unless they are explicitly instantiated.
Also, you did not write using namespace std; in func.h (not that you should write it anywhere, especially headers). As a result, you need to write std::deque instead of merely deque.
So func.h should look like the following:
#include <iostream>
#include <deque>
template<typename T>
void display(const std::deque<T>& d)
{
for (auto e : d)
std::cout << e << std::endl;
}

How to import a class in another C++ header file? [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
I meet a problem when constructing a class. class "Graph" import a class "Bag" in another file and use "Bag" as its component.
//Graph.h
#ifndef GRAPH_H
#define GRAPH_H
#include <fstream>
#include <iostream>
#include <vector>
#include "Bag.h"
class Bag;
class Graph
{
public:
Graph(int V);
Graph(std::ifstream& in_file);
int getV() { return V; }
int getE() { return E; }
void addEdge(int v, int w);
void showadj() ;
private:
int V;
int E;
std::vector<Bag> adj;
};
#endif
And "Bag.h" is as follow:
//Bag.h
#ifndef BAG_H
#define BAG_H
#include <vector>
#include <iostream>
class Bag
{
public:
Bag();
void addBag(int i) { content.push_back(i); }
void showBag();
private:
std::vector<int> content;
};
#endif
Graph.cpp:
//Graph.cpp
#include "Graph.h"
#include "Bag.h"
Graph::Graph(int V) : V(V), E(0)
{
for (int i = 0; i < V; i++)
{
Bag bag;
adj.push_back(bag);
}
}
Bag.cpp(sorry, forget it):
#include "Bag.h"
void Bag::showBag()
{
for (int i : content)
{
std::cout << i << " ";
}
}
When I try to complie these two classes, an error comes out saying:
C:\Users\ADMINI~1\AppData\Local\Temp\ccMj4Ybn.o:newtest.cpp:(.text+0x1a2): undef
ined reference to `Bag::Bag()'
collect2.exe: error: ld returned 1 exit status
You need to also implement your constructor Bag::Bag() as it is missing in your Bag.cpp file.
This is what the error tells you. If you don't need the constructor, then you should remove it from your class definition, which would also solve this error.
An alternative would be to provide an empty constructor in your Bag.h file
class Bag
{
public:
Bag() {}
...
}

How to properly build a template class that inherits from an interface and has a separate implementation file.

Here is the code for the question:
PlainInterface.h
/** PlainInterface.h */
#ifndef _PLAIN_INTERFACE
#define _PLAIN_INTERFACE
#include <vector>
template <class ItemType>
class PlainInterface{
public:
virtual int getSize () const = 0;
};
#endif
Plain.h
/** Plain.h */
#ifndef _PLAIN
#define _PLAIN
#include "PlainInterface.h";
template <class ItemType>
class Plain: public PlainInterface < ItemType > {
private:
std::vector<ItemType> a;
public:
Plain();
~Plain();
int getSize() const;
};
#include "Plain.cpp"
#endif
Plain.cpp
/* Plain.cpp */
#include <iostream>
#include "Plain.h"
//Constructors
template <class ItemType>
Plain<ItemType>::Plain() {
std::cout << "Created\n";
}
template <class ItemType>
Plain<ItemType>::~Plain() {
std::cout << "Destroyed\n";
}
template <class ItemType>
int Plain<ItemType>::getSize() const { return 0; }
So according to this question it said that you can either have all of the implementation in the header file, or put #include "Plain.cpp" at the end of the "Plain.h" file, or put the explicit instantiations at the end of the "Plain.cpp" file. I would like to keep the files seperate and not limit what is allowed into the templates. I tried the second option and it didn't work.
The errors that I am getting are that the constructor/deconstructor/getSize definitions in Plain.cpp are already defined. What am I doing wrong here?
You should remove #include "Plain.h" in your .cpp file, as you are creating a circular include otherwise.
Example:
//a.h
...
#include "b.cpp"
//b.cpp
#include "a.h"
a will include b, b will include a, and so on. This is probably why the second option you mentioned didn't work.
Here another answer that applies to your problem (I think): https://stackoverflow.com/a/3127374/2065501

Linker error when including an .h file but disappears when including the correspondent .cpp file

This is strange. How can it possibly be that I get an error when I'm including an .h file (GeneralSearch.h) but everything seems to work just fine when, instead, I include the .cpp file (GeneralSearch.cpp)?
.h file
#ifndef GENERALSEARCH_H_
#define GENERALSEARCH_H_
#include "Problem.h"
#include "Node.h"
template <class T>
class GeneralSearch
{
public:
const Node* treeSearch(const Problem &problem) const;
const Node* graphSearch(const Problem &problem, T &fringe = T()) const;
private:
void expand(const Node &node, const Problem &problem, list<const Node*> &out) const;
};
#endif
.cpp file
#include "GeneralSearch.h"
template <class T>
void GeneralSearch<T>::expand(const Node &node, const Problem &problem, list<const Node*> &out) const
{
...
}
template <typename T>
const Node* GeneralSearch<T>::treeSearch(const Problem &problem) const
{
...
}
template <typename T>
const Node* GeneralSearch<T>::graphSearch(const Problem &problem, T &fringe = T()) const
{
...
}
the program file - WORKING
#include "GeneralSearch.cpp"
#include "DummyProblem.h"
#include "DepthFirstSearch.h"
#include <queue>
int main (int argc, char* argv[]){}
the program file - NOT WORKING
#include "GeneralSearch.h"
#include "DummyProblem.h"
#include "DepthFirstSearch.h"
#include <queue>
int main (int argc, char* argv[]){}
The linker tries to find the definitions of unresolved names while linking. In the second case, the linker is not able to find the definitions of the member functions of the class GeneralSearch and hence you get the error.