Error in C++ : redefinition of class constructor using templates - c++

Anybody know how I can fix these errors?
i have been looking at it for a while and just cannot figure out what to do.
Error:
indexList.cpp:18: error: redefinition of `indexList<T>::indexList()'
indexList.cpp:18: error: `indexList<T>::indexList()' previously declared here
indexList.cpp:30: error: redefinition of `bool indexList<T>::append(T)'
indexList.cpp:30: error: `bool indexList<T>::append(T)' previously declared here
cpp file:
//
//
//
//
//
//
#include "indexList.h"
#include <iostream>
using namespace std;
//constuctor
//Descriptions: Initializes numberOfElement to 0
// Initializes maxSize to 100
//Parameters: none
//Return: none
template <class T>
indexList<T>::indexList()
{
numberOfElements = 0;
maxSize = 100;
}
//Name: append
//Purpose: Adds element to the end of the list. If array is full, returns false
//Paramters: value - thing to append
//Return: true if append succeeds, false otherwise
template <class T>
bool indexList<T>::append(T value)
{
if (maxSize > numberOfElements)
{
list[numberOfElements] = value;
numberOfElements ++;
return true;
}
else
return false;
}
I didn't put all the the cpp file because the rest of the errors are similar to the ones above, and it is quite long
header:
#include <iostream>
using namespace std;
#ifndef INDEXLIST_H
#define INDEXLIST_H
template <class T>
class indexList
{
public:
indexList();
bool append(T value);
bool insert(int indx, T value);
bool replace(int indx, T newValue);
bool retrieve(int indx, T &value) const;
bool remove(int indx);
void sort();
int search(T value) const;
private:
T list[100];
int numberOfElements;
int maxSize;
};
template <class T>
ostream &operator<<(ostream &outStream, const indexList<T> &lst);
#include "indexList.cpp"
#endif
I did put the entire header

Each of your two files tries to include the other, which can cause the preprocessor to output some repeated code.
Take the #include "indexList.h" out of the file indexList.cpp.
Also, your build process should not attempt to compile indexList.cpp into an object file.
Another way to arrange things would be to just put all the contents you currently have in indexList.cpp near the end of indexList.h, and there would be no indexList.cpp file at all.

What you've done is ok, but you must realise that the .cpp file should not itself be compiled into an object - instead, just include the .h file from your application code:
// main.cc
#include "indexList.h"
int main()
{
indexList<int> il;
}
c++ -o main main.cc
I'd bet it's because you've tried to do a c++ -c indexList.cpp or c++ indexList.cpp that you get the errors (or perhaps your make tool is trying that automatically for all .cpp files in your source code directories - you could try renaming indexList.cpp to indexList.inl or .inc or whatever - remember to change the name in indexList.h too - to see if that fixes the problem), as in that situation the definitions are seen twice: once as the compile includes indexList.h, and again as it finishes compiling indexList.cpp.
There's no need to include indexList.h from within the .cpp anyway - that makes it look as if the indexList.cpp is designed for separate compilation.

Put any of your templated methods in an indexList.inl file, and include that from your header. Don't include the header from this file.
Put any other methods in your indexList.cpp file. Include the header from this file.

Related

Template file not working correctly in CodeLite?

Every time I create a new project in my workplace I run into the problem with templates. For example, I'll create a new class, which CodeLite will create a .h file and a .cpp file for me, and then I'll change that .cpp file into a .template by renaming the file. It sometimes works, and sometimes doesn't. Sometimes I have to clean my workplace for it to work, other times I need to exit out of CodeLite and reopen it. This time these solutions are not working for me, but maybe I am missing something. Here's my code:
.h file
#ifndef TABLE1_H
#define TABLE1_H
#include <cstdlib> // Provides size_t
namespace main_savitch_12A
{
template <class RecordType>
class table
{
public:
// MEMBER CONSTANT -- See Appendix E if this fails to compile.
static const std::size_t CAPACITY = 811;
// CONSTRUCTOR
table( );
// MODIFICATION MEMBER FUNCTIONS
void insert(const RecordType& entry);
void remove(int key);
// CONSTANT MEMBER FUNCTIONS
bool is_present(int key) const;
void find(int key, bool& found, RecordType& result) const;
std::size_t size( ) const { return used; }
private:
// MEMBER CONSTANTS -- These are used in the key field of special records.
static const int NEVER_USED = -1;
static const int PREVIOUSLY_USED = -2;
// MEMBER VARIABLES
RecordType data[CAPACITY];
std::size_t used;
// HELPER FUNCTIONS
std::size_t hash(int key) const;
std::size_t next_index(std::size_t index) const;
void find_index(int key, bool& found, std::size_t& index) const;
bool never_used(std::size_t index) const;
bool is_vacant(std::size_t index) const;
};
}
#include "table1.template" // Include the implementation.
#endif
.template file
template<class RecordType>
table<RecordType>::table(){
used = 32;
}
main file
#include <stdio.h>
#include "table1.h"
int main(int argc, char **argv)
{
printf("hello world\n");
return 0;
}
My template and my .h files are called table1. The error I am getting when I run the program is in the template file. It reads: "table does not name a type" How can I fix this issue?
In your template implementation your are missing the namespace, use this:
template <class RecordType>
main_savitch_12A::table<RecordType>::table()
{
used = 32;
};

C++ class template undefined reference to function [duplicate]

This question already has answers here:
undefined reference to template function [duplicate]
(2 answers)
Closed 6 years ago.
I keep getting undefined reference when i call the two functions from my template class "add" and "greater" in my main function.
So, i have:
number.h
#ifndef NUMBER_H
#define NUMBER_H
template <class T>
class number {
public:
T x;
T y;
number (int a, int b){
x=a; y=b;}
int add (T&);
T greater ();
};
#endif
number.cpp
#include "number.h"
template <class T>
int number<T>::add (T& rezAdd){
rezAdd = x+y;
return 1;
}
template <class T>
T number<T>::greater (){
return x>y? x : y;
}
And my main file is: resolver.cpp
#include <stdio.h>
#include <stdlib.h>
#include "number.h"
int main (int argc, char **argv) {
int aux;
number<int> c(3,5);
c.add(aux);
printf ("number added [%d]\n", c.add(aux));
printf ("greater number: [%d]\n", c.greater());
return 0;
}
The errors that i keep getting are:
g++ -Wall -o tema1 resolver.cpp number.cpp
/tmp/ccX483J4.o: In function `main':
resolver.cpp:(.text+0x34): undefined reference to `number<int>::add(int&)'
resolver.cpp:(.text+0x47): undefined reference to `number<int>::add(int&)'
resolver.cpp:(.text+0x64): undefined reference to `number<int>::greater()'
collect2: ld returned 1 exit status
make: *** [all] Error 1
Thanks for the help in advance!
I prefer to have all of my functions in the .cpp file, regardless of whether they are template functions or regular functions. And there is a way to do that with some basic #ifndef magic. Here's what you can do:
main.cpp
#include "myclass.hpp"
int main()
{
// ...
}
myclass.hpp
#ifndef MYCLASS
#define MYCLASS
template<class T>
class MyClass
{
T val;
public:
MyClass(T val_);
}
#define MYCLASS_FUNCTIONS
#include "myclass.cpp"
#endif
myclass.cpp
#ifndef MYCLASS_FUNCTIONS
#include "myclass.hpp"
// regular functions:
// ...
#else
// template functions:
template<class T>
MyClass<T>::MyClass(T val_)
:val(val_)
{}
// ...
#endif
Here's how the precompiler sees it. We have two .cpp files.
When we compile main.cpp we:
include myclass.hpp
check that MYCLASS is undefined, and it is
define it
give compiler the definitions of the generated class (from template class)
include myclass.cpp
define MYCLASS_FUNCTIONS
check if MYCLASS_FUNCTIONS is defined, it is
give compiler the definitions of the generated functions (from template functions)
When we compile myclass.cpp
check if MYCLASS_FUNCTIONS is defined, it isn't
include myclass.hpp
check that MYCLASS is undefined, and it is
define it
give compiler the definitions of the class
include myclass.cpp
include myclass.hpp again
this time MYCLASS is defined so do nothing inside, return to myclass.cpp
check if MYCLASS_FUNCTIONS is defined, it is
give compiler the definition of the generated functions (from template functions)
exit include twice
pass to the compiler all the regular functions
Your class is named wrong. Your class is named cai where all your functions belong to a class named number: http://ideone.com/ZayX0c
One more thing.. you cannot have templates in the .cpp file. Template functions/defintions go in the header along with the class declaration. This is the reason for your undefined function error. Non-template functions go in the .cpp.
#include <cstdio>
#include <cstdlib>
template <class T>
class number {
public:
T x;
T y;
number (int a, int b){
x=a; y=b;}
int add (T&);
T greater ();
};
template <class T>
int number<T>::add (T& rezAdd){
rezAdd = x+y;
return 1;
}
template <class T>
T number<T>::greater (){
return x>y? x : y;
}
int main (int argc, char **argv) {
int aux;
number<int> c(3,5);
c.add(aux);
printf ("number added [%d]\n", c.add(aux));
printf ("greater number: [%d]\n", c.greater());
return 0;
}
Move the definitions of the add and greater function templates into your number.h.
Remember that add and greater aren't functions, they're function templates. To create actual functions, the compiler has to instantiate the template for specific types, such as int, and it can only do that if it has access to the template's definition at the point where it discovers that an instance is needed.
When you compile number.cpp, the compiler has access to the templates' definitions, but it doesn't see any code that requires a specific instance (such as number<int>), so it doesn't generate instances.
When you compile resolver.cpp, the compiler sees that it needs to instantiate those templates for the int type, but it can't since it doesn't have their definitions. So it generates "external references", basically notes telling the linker to look for those functions in some other object file.
The result is that the function templates don't get instantiated in either object file — in one because the compiler didn't know that it should, and in the other because it couldn't — so when the linker goes looking for them (to resolve those external references), it can't find them. That's why you get the error.
Moving the template function definitions into the header makes them visible to the compiler while it's compiling main.cpp, so it's able to instantiate those functions for the int type. Function templates typically need to be defined in header files, rather than .cpp files, for exactly this reason.

error C2995:function template has already been defined

there are many solutions to this question bot nothing answers my case.
I am using VS 2008.I am tring to create a map using Binary search tree
#ifndef _map_h
#define _map_h
#include<string>
using namespace std;
template <typename ValType>
class Map
{
public:
Map();
~Map();
ValType getvalue(string key);
void add(string key,ValType value);
private:
struct node{
string key;
ValType value;
node *right;
node *left;
};
node *root;
node *treeSearch(string key,node *t);
void treeEnter(string key,ValType value,node *&t);
};
#include"map.cpp"
#endif
map.cpp
#include<string>
#include<iostream>
#include"map.h"
using namespace std;
template <typename ValType>
Map<ValType>::Map(){
root=NULL;
}
template <typename ValType>
Map<ValType>::~Map(){
delete root;
}
template <typename ValType>
ValType Map<ValType>::getvalue(string key){
node *found=treeSearch(key,root);
if(found==NULL)
cout<<"Couldnot Found the node";
else return found->value;
}
template <typename ValType>
typename Map<ValType>::node *Map<ValType>::treeSearch(string key,node *t){
if(t==NULL) return NULL;
if(t->key==key) return t;
if(t->key>key) treeSearch(key,t->left);
else treeSearch(key,t->right);
}
template <typename ValType>
void Map<ValType>::add(string key,ValType value){
treeEnter(key,value,root);
}
template <typename ValType>
void Map<ValType>::treeEnter(string key,ValType value,node *&t){
if(t==NULL){
t->value=value;
t->key=key;
t->left=NULL;
t->right=NULL;
}
else if(t->key==key) t->value=value;
else if(t->key>key) treeEnter(key,value,t->left);
else treeEnter(key,value,t->right);
}
Error:For all the functions its saying that they are already been defined.
I am following Stanford online course and the same worked for the instructor(she was using mac)
You have included map.h into map.cpp and map.cpp into map.h. The include guards in map.h will prevent multiple inclusion of map.h and will prevent infinite recursive inclusion. However, if you feed map.cpp to the compiler directly (which is what you are apparently trying to do) it will include map.h once and then map.h will include map.cpp itself one more time. This is what is causing the error.
If you want to implement your template as .cpp file included into .h file, you can do that. This is weird, but it can be forced to work. First and foremost, if you decided to #include your map.cpp, then don't even attempt to compile your map.cpp. Don't feed your map.cpp directly to the compiler. Also, remove #include "map.h" from that .cpp file. There's absolutely no point in doing that.
Your program will have other implementation files, like, say, myprogram.cpp, which will use your map. That myprogram.cpp should include map.h. That myprogram.cpp is what you will feed to the compiler. That way it will work as intended. But trying to compile map.cpp directly will only result in errors.
A better idea though would be not to put anything into a .cpp file. Either put everything into .h file or, if you really want to have it split that way, rename your .cpp file into something else to make it clear to everyone that this is not a translation unit.
In my case, I missed include guards or #pragma once at the top of the header where I defined a template function.

Templates and separate compilation

I want to write a program in C++ with separate compilation and I wrote this:
main.cpp
#include <iostream>
#include "Stack.h"
using namespace std;
int main(int argc,char* argv[])
{
Stack<int> st;
st.push(1);
return 0;
}
Stack.h
#ifndef _STACK_H
#define _STACK_H
template<typename T>
class Stack
{
private:
struct Node
{
Node* _prev;
T _data;
Node* _next;
};
int _size;
Node* _pos;
public:
Stack();
T pop();
void push(T const &el);
int getSize() const;
};
#endif
Stack.hpp
#include "Stack.h"
#include <malloc.h>
template <typename T>
Stack<T>::Stack()
{
_size = 0;
_pos = (Node*)malloc(sizeof(Node));
_pos->_prev = NULL;
_pos->_next = NULL;
}
template <typename T>
T Stack<T>::pop()
{
if (_size == 0)
return NULL;
T tmp = _pos->_data;
if (_pos->_prev == NULL)
free(_pos);
else
{
_pos->_prev->_next = _pos->_next;
if (_pos->_next != NULL)
{
_pos->_next->_prev = _pos->_prev;
}
free(_pos);
}
_size--;
return tmp;
}
template <typename T>
void Stack<T>::push(T const &el)
{
Node* n = (Node*)malloc(sizeof(Node));
_pos->_next = n;
n->_prev = _pos;
n->_data = *el;
_pos = n;
_size ++;
}
template<typename T>
int Stack<T>::getSize() const {return _size;};
I compiled the program with g++ and I get this error:
ccyDhLTv.o:main.cpp:(.text+0x16): undefin
ed reference to `Stack<int>::Stack()'
ccyDhLTv.o:main.cpp:(.text+0x32): undefin
ed reference to `Stack<int>::push(int const&)'
collect2: ld returned 1 exit status
I know that the problem is because I'm using templates but I do not know how to fix it.
OS - Windows
compilation line - g++ main.cpp Stack.h Stack.hpp -o main.exe
Template classes need to have the method definitions inside the header file.
Move the code you have in the .cpp file inside the header, or create a file called .impl or .imp, move the code there, and include it in the header.
The compiler needs to know the method definitions to generate code for all specializations.
Before you ask, no, there is no way to keep the implementation outside the header.
I would say it will be more pragmatic to first understand how separate compilation works for normal (untempelated) files and then understand how g++ compiler does it for template.
First in normal files, when the header file containing only the declarations are #included in main file, the preprocessor replaces the declarations from the header and puts it to the main file. Then after the preprocessing phase is over, the compiler does one by one compilation of the pure C++ source code contained in .cpp files and translates it into object file. At this point the compiler doesn't mind the missing definitions (of functions/classes) and the object files can refer to symbols that are not defined. The compiler, hence can compile the source code as long as it is well formed.
Then during the linking stage the compiler links several files together and it is during this stage the linker will produce error on missing/duplicate definitions. If the function definition is correctly present in the other file then the linker proceeds and the function called from the main file is successfully linked to the definition and can be used.
For templates, things work differently. It will be illustrative to consider an example, so I pick a simple one:
consider the header file for template array class:
array.h
#ifndef _TEMPLATE_ARRAY_H_
#define _TEMPLATE_ARRAY_H_
template <class T>
class Array
{
private:
T *m_list;
int m_length;
public:
Array() //default constructor
{
m_list = nullptr;
m_length = 0;
}
Array(int length)
{
m_list = new T[length];
m_length = length;
}
~Arrary()
{
delete[] m_list;
m_list = nullptr;
}
//undefined functions
int getLength();
T getElement(const int pos);
};
and the corresponding array.cpp file :
include "array.h"
template <class T>
array<T>::getLength()
{ return m_length; }
template <class T>
T Array<T>::getElement(const int pos)
{ return m_list[pos]; }
Now consider the main file where two instances of the templated object array, one for int and another for double is created.
main.cpp
#include "array.h"
#include <iostream>
int main()
{
Array<int> int_array;
Array<double> double_array;
std::cout << int_array.getLength() <<"\n";
std::cout << double_array.getLength() << "\n";
}
When this piece of code is compiled, the preprocessor first copies the template declarations from the header file to the main file as usual. Because in the main file Array< int > and Array< double > objects are instantiated, compiler instantiates two different definitions of Array class, one each for double and int and then instantiate the Array objects in the main.cpp file.
Note till this point the function definitions for Array< int >::getLength() and Array< double >::getLength() is still missing in the main.cpp file but since the source code is well formed the compiler compiles the main.cpp file without any hassle. In short there's no difference b/w templated object/function compilation and non-templated function compilation till now.
In the meanwhile the code file for array.cpp containing the template function definitions for Array< T >::getLength() and Array< T >::getElement() is compiled, but by this time the compiler would have forgotten that main.cpp needs Array< int >::getLength() and Array< double >::getLength() and would happily compile the code array.cpp without generating any instances for int and double version of the function definition needed by the main.cpp file. (Remember that compiler compiles each file separately!)
It is during the linking phase horrible template errors start popping because of the missing function definitions for int and double version of template function definition that are required by the main file. In the case of non-template declarations and definitions, the programmer makes sure to define the sought function in a file which can be linked together with the file calling the function. But in the case of templates, the linker which executes after the compilation phase, cannot do a task that a compiler is suppose to do, i.e generate a code, in this case for int and double type of the template function
There are ways to get around this
Having gone through the entire story, one can easily conclude that the entire fuss up around template separate compilation is due to linkage (i.e) if all codes are written correctly, class and functions declared in header and defined in another separate file). Ways of getting around this are :
Define the class and functions in the header files themselves rather than in separate file so that the contents of header file when included in the main file, includes the templated definitions which cause appropriate instances of necessary functions to be defined by the compiler.
Instantiate the type definitions you know you will need in the separate file where the template definitions are written. This will then directly be linked to the function calls in the main file.
Another way to get around this is to name the .cpp file where definitions are written to .inl* file (from the e.g drawn above, chagne array.cpp to array.inl); inl means inline and include the .inl file from the bottom of the header file. This yields the same result as defining all functions within the header file but helps keeping the code a little cleaner.
There's another way, i.e #include .cpp file with templated definitions in the main file which I personally don't prefer because of non-standard usage of #include.
It is absolutely possible to have templates and separate compilation, but only if you know in advance for which types the template will be instantiated.
Header file sep_head.h:
template< typename T >
class sep{
public:
sep() {};
void f();
};
Main:
#include "sep_head.h"
int main() {
sep<int> s; s.f();
sep<double> sd; sd.f();
sep<char> sc; sc.f();
return 0;
}
Implementation:
#include "sep_head.h"
template< typename T >
void sep<T>::f() {}
template class sep<int>;
template class sep<double>;
template class sep<char>;

failing to invoke template class, c++

I've defined a template class like so (providing .hpp file):
#ifndef PERSOANLVEC_H_
#define PERSOANLVEC_H_
#include <vector>
using namespace std;
template<class T, class PrnT> class PersoanlVec {
public:
PersoanlVec();
~PersoanlVec();
void push_back(T t);
void erase(int index);
PersoanlVec& operator[](int index);
const PersoanlVec& operator[](int index) const;
void print() const;
size_t size();
private:
vector<T> _vector;
};
#endif /* PERSOANLVEC_H_ */
Now, everything compiles ok with this class. When I try to use it I get
undefined reference to PersoanlVec<Person, Person>::PersoanlVec()'.
Here's where I call it:
#include "Person.h"
#include "PersoanlVec.hpp"
#include <cstdlib>
int main(void)
{
Person p1("yotam");
Person p2("yaara");
PersoanlVec<Person,Person> *a = new PersoanlVec<Person,Person>(); //<---ERROR HERE
return EXIT_SUCCESS;
}
This is my first try with templates, its not very clear for me obviously. I DO have a constructor with no parameters, Any ideas?
Thanks!
Do you have the content of your constructor and functions in a .cpp file? If yes, there's your problem. Put them in the header file, possible just inline in the class itself:
template<class T, class PrnT> class PersoanlVec {
public:
PersoanlVec(){
// code here...
}
~PersoanlVec(){
// code here...
}
void push_back(T t){
// code here...
}
void erase(int index){
// code here...
}
PersoanlVec& operator[](int index){
// code here...
}
const PersoanlVec& operator[](int index) const{
// code here...
}
void print() const{
// code here...
}
size_t size(){
// code here...
}
private:
vector<T> _vector;
};
For the reason, have a look here.
I am pretty sure you just forgot to add the file to the compilation process. Be careful with your misspelling, since that can cause generic pain.
Whenever you have different compilation units (classes for example, each with their .h/.cpp), your classes need to know of the interfaces, reason for which you normally include the header files, yet the compiler also needs to know the implementations so that it can bind together your binary file.
As such, you will need to call the compiler passing all the .cpp files in your project to it, otherwise it will fail letting you know you are referencing unimplemented pieces.
You need to have all of your template function definitions held in the header file rather than the CPP file - this is basically because the template definition will be used multiple times to create multiple types depending on what parameters you pass in to it as type parameters around your code. The only template related functions that should ever be defined in the CPP file are template specialization functions - those where you want to explicitly say (if user passed in type A and B then do this specifically instead of the default action).