This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 7 years ago.
The solution to the duplicate question did not work
I have the following files:
ListaEnc.hpp
#include "Elemento.hpp"
template<typename T>
class ListaEnc {
public:
ListaEnc();
~ListaEnc();
// inicio
void adicionaNoInicio(const T& dado);
T retiraDoInicio();
void eliminaDoInicio();
T pegarHead();
// posicao
void adicionaNaPosicao(const T& dado, int pos);
int posicao(const T& dado) const;
T* posicaoMem(const T& dado) const;
bool contem(const T& dado);
T retiraDaPosicao(int pos);
// fim
void adiciona(const T& dado);
T retira();
// especifico
T retiraEspecifico(const T& dado);
void adicionaEmOrdem(const T& data);
// outras
bool listaVazia() const;
bool igual(T dado1, T dado2);
bool maior(T dado1, T dado2);
bool menor(T dado1, T dado2);
void destroiLista();
int pegarTamanhoLista();
private: //trocar pra private
Elemento<T>* head;
int size;
};
ListaEnc.cpp
#include "ListaEnc.hpp"
#include <cstdlib>
#include <iostream>
template<typename T>
ListaEnc<T>::ListaEnc()
{
...
}
main.cpp
#include "ListaEnc.hpp"
using namespace std;
int main(int argc, char** argv)
{
double x1, y1;
x1 = 2; y1 = 4.2;
ListaEnc<int>* teste = new ListaEnc<int>();
return 0;
}
This should compile just fine, but I get an undefined reference error to ListaEnc on main.cpp. I have more files in which the reference to ListaEnc is also undefined, but I tried isolating it and still can't get it to work. Does anyone understand why this is happening?
edit: More specifically, there is an undefined error to the constructor and destructor of ListaEnc
You can't separate declaration from implementation when you instantiate a template class. Combine your code to a single file and include that in your main.cpp.
Or, even go a step further and implement the functions inline in your class declaration if that suits your coding style.
Related
This question already has answers here:
Separating class code into a header and cpp file
(8 answers)
Closed 4 months ago.
fyi I have looked at the other posts on this topic but I either didn't understand or didn't find my problem in them.
pretty much I am trying to put a class into a cpp and .h file, when I compile the code I get a warning saying "warning: inline function 'float map::get_mapped_value()' used but never defined.
And when I build the code I get an error saying undefined reference to 'map::get_mapped_value'
below are the code in each file
I thought I had all my includes correct, but maybe I am missing something, I am new to separating classes into seperate file, so any help would be greatly appreciated.
Thanks in advance, Dean.
map.cpp
#include "map.hpp"
#include <stdio.h>
#include <iostream>
using namespace std;
//------------------------Constructor definitions--------------------------
map::map(float Val_to_map_, float in_min_, float in_max_, float out_min_, float out_max_)
: Val_to_map(Val_to_map_)
, in_min(in_min_)
, in_max(in_max_)
, out_min(out_min_)
, out_max(out_max_)
{
}
//-------------------------------------------------------------------------
//------------------------Copy Constructor definitions---------------------
map::map(const map& mp)
: Val_to_map(mp.Val_to_map)
, in_min(mp.in_min)
, in_max(mp.in_max)
, out_min(mp.out_min)
, out_max(mp.out_max)
{
}
//-------------------------------------------------------------------------
//-----------------------equals function-------------------------------------
map& map::operator=(const map& mp)
{
if(this == &mp)
return (*this);
Val_to_map = mp.Val_to_map;
in_min = mp.in_min;
in_max = mp.in_max;
out_min = mp.out_min;
out_max = mp.out_max;
return (*this);
}
//---------------------------------------------------------------------------
//-------------------get function definitions--------------
inline float map::get_mapped_value()
{
return (float((Val_to_map - in_min) * (out_max - out_min) / (in_max - in_min) + out_min));
}
//-----------------------------------------------------------
//-------------------set function definitions----------------
inline void map::set_Val_to_map(float _Val_to_map)
{
Val_to_map = _Val_to_map;
}
inline void map::set_in_min(float _in_min)
{
in_min = _in_min;
}
inline void map::set_in_max(float _in_max)
{
in_max = _in_max;
}
inline void map::set_out_min(float _out_min)
{
out_min = _out_min;
}
inline void map::set_out_max(float _out_max)
{
out_max = _out_max;
}
//-----------------------------------------------------------
map.h
#ifndef MAP_HPP
#define MAP_HPP
using namespace std;
class map
{
public:
//----------------Special Member functions-----------------
map(float Val_to_map_, float in_min_, float in_max_, float out_min_, float out_max_); // accepted arguments
map(const map& m); // copy constructor
map& operator=(const map& m); // Equals function
~map()
{
} // destructor
//---------------------------------------------------------
//-----------------get functions-----------------
inline float get_mapped_value();
//------------------------------------------------
//-----------------set functions-----------------
inline void set_Val_to_map(float Val_to_map);
inline void set_in_min(float in_min);
inline void set_in_max(float in_max);
inline void set_out_min(float out_min);
inline void set_out_max(float out_max);
//------------------------------------------------
private:
float Val_to_map;
float in_min; // min Vref
float in_max; // max Vref
float out_min; // min output voltage from psu
float out_max; // max output voltage from psu
};
#endif // MAP_HPP
main.cpp
main(){
map voltage(1, map_in_min, map_in_max, map_out_min, map_out_max);
cout << "Mapped val: " << voltage.get_mapped_value() << endl;
}
You declared the function get_mapped_value as an inline function
inline float get_mapped_value();
So its definition shall be in each compilation unit where it is used.
The simplest way to resolve the problem is to include the function definition either directly in the class definition where it is declared or in the header where the class definition is present.
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 3 years ago.
I tried to make an Array template class but when I try to build the compiler fails to link the constructor and the method and I get :
undefined reference to `Array::Array()
undefined reference to `Array::getSize()
Here is the header file:
#pragma once
template<typename type, int length>
struct Array{
public:
Array();
int getSize();
private:
type data[length];
int m_length;
};
The Array.cpp file:
#include "Array.h"
template<typename t, int l>
Array<t, l>::Array()
{
m_length = l;
}
template<typename type, int length>
Array<type, length>::getSize()
{
return m_length;
}
And the main function:
#define LOG(x) cout<<x<<endl
int main()
{
Array<int, 10> array;
LOG(array.getSize());
}
If someone has any idea about why I am getting this, I would really appreciate.
You need to either put your implementation into the header files, or define the usage (instantiation of the template arguments) in the source file
I want to have a singleton in my project but some errors occur
this is my codes in three separate files.:
//---------------My main.cpp code
#include <iostream>
#include "Sports/BBVB.h"
int main() {
bbvb;
return 0;
}
// ---------------------------my BBVB.h code
#ifndef SAMAVAR_BBVB_H
#define SAMAVAR_BBVB_H
typedef struct VBResult{
int set1=-1;
int set2=-1;
int set3=-1;
int set4=-1;
int set5=-1;
}VBResult;
#include "Sport.h"
#include "../TournamentStuf/Tournament.h"
class BBVB: public Sport {
protected:
vector<Tournament<VBResult>> tours;
public:
static BBVB& getInstance(){
static BBVB b;
return b;
}
private:
BBVB(){}
public:
BBVB(BBVB const&)=delete;
void operator=(BBVB const&) = delete;
//-------------Setter------------
//------------Getter-------------
vector<Tournament<VBResult>> getTours() const;
Tournament<VBResult> getTourById(int id) const;
//----------Others---------------
void addTour(Tournament<VBResult> v);
};
BBVB &bbvb=BBVB::getInstance();
#endif //SAMAVAR_BBVB_H
//------------------my Store and restore code
#ifndef SAMAVAR_STOREANDRESTORE_H
#define SAMAVAR_STOREANDRESTORE_H
#include "../Sports/BBVB.h"
#include "../Sports/PingPong.h"
#include "../Sports/Wrestling.h"
void Start(BBVB &b);
void Update(const BBVB &b);
void Start(PingPong &p);
void Update(const PingPong &p);
void Start(Wrestling &w);
void Update(const Wrestling &w);
#endif //SAMAVAR_STOREANDRESTORE_H
I have a bbvb instance of BBVB but it says you have multiple definitions of it.
I'm new to Clion and I don't have enough information about somethings like cmake and I feel the problem is because of it.
I want to have something like cout and cin in iostream.so by including my BBVB I can access this object.
Clion shows error below:
CMakeFiles\Samavar.dir/objects.a(BBVB.cpp.obj):BBVB.cpp:(.bss+0x0): multiple definition of `bbvb'
CMakeFiles\Samavar.dir/objects.a(main.cpp.obj):main.cpp:(.bss+0x0): first defined here
CMakeFiles\Samavar.dir/objects.a(StoreAndRestore.cpp.obj):StoreAndRestore.cpp:(.bss+0x0): multiple definition of `bbvb'
CMakeFiles\Samavar.dir/objects.a(main.cpp.obj):Samavar-master/Sports/BBVB.h:24: first defined here
collect2.exe: error: ld returned 1 exit status
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am very new to C++ and I did search previous answers for my questions "x does not name a type" from StackOverflow. However, I still couldn't find how my code violating any causing this compilation error.
My environment is Ubuntu c++-8 and I ran on the terminal as g++-8 -pedantic -std=c++14 -Wall -weffc++ -Wextra Range.c++ -o Range
I got "Range does not name a type" and 'b' was not declared in this scope. However, I did declare 'b' and 'e' as an int of iterator Range template type. Please kindly help.
#include <iostream>
#include <cassert>
#include <iterator>
using namespace std;
template
class RangeIterator {
public:
using iterator_category = input_iterator_tag;
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = T*;
using reference = T&;
private:
T _v;
public:
RangeIterator (const T& v) :
_v (v)
{}
bool operator == (const RangeIterator& rhs) const {
return (_v == rhs._v);}
bool operator != (const RangeIterator& rhs) const {
return !(*this == rhs);}
const T& operator * () const {
return _v;}
RangeIterator& operator ++ () {
++_v;
return *this;}
void test1(){
const RangeIterator<int> x(2,2);
const RangeIterator<int>::iterator b = begin(x);
const RangeIterator<int>::iterator e = end(x);
assert(b == e);
}
int main(){
test1();
return 0;}
you seem to forgotten to include the header file that contains the declaration of the template class named Range.
if you already have your header file. you just have to include it in your headers list
#include <iostream>
#include <cassert>
#include <iterator>
#include "Range.h" //this is an example. it could be named differely on your end.
Your Range.h file should contain the class declaration for Range which would look something like this.
template<typename Type>
class Range
{
public:
Range(int a, int b);
//...
//...
};
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;
};