function ... has already a body & function template has already been defined - c++

I have this header file:
Utility.h:
#pragma once
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <Windows.h>
using namespace std;
template<std::size_t> struct int_ {};
template <class Tuple, size_t Pos>
std::ostream& print_tuple(std::ostream& out, const Tuple& t, int_<Pos>);
struct Timer {
public:
Timer();
void start();
double getMilliSec();
private:
LARGE_INTEGER frequency; // ticks per second
LARGE_INTEGER t1, t2; // ticks
};
//...
#include "Utility.cpp"
And this implementation file:
Utility.cpp:
#include "Utility.h"
template <class Tuple, size_t Pos>
std::ostream& print_tuple(std::ostream& out, const Tuple& t, int_<Pos>) {
...
}
Timer::Timer() {
// get ticks per second
QueryPerformanceFrequency(&frequency);
}
void Timer::start() {
QueryPerformanceCounter(&t1);
}
double Timer::getMilliSec() {
QueryPerformanceCounter(&t2);
return (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
}
Which returns this error:
error C2995: 'std::ostream &print_tuple(std::ostream &,const Tuple &,int_<Pos>)': function template has already been defined
error C2084: function 'Timer::Timer(void)' already has a body
...
The problem is not about guards (as suggested in this question) since I use #pragma once
I`ve read about of implementing .tpp files for template class implementation, but I find it an horrible solution, since Visual Studio will format nothing from this file.
trying to define Utility.tpp: (WRONG SOLUTION)
So I substituted #include "Utility.cpp with #include "Utility.tpp in Utility.h and define...
Utility.tpp
Timer::Timer() {
// get ticks per second
QueryPerformanceFrequency(&frequency);
}
void Timer::start() {
QueryPerformanceCounter(&t1);
}
double Timer::getMilliSec() {
QueryPerformanceCounter(&t2);
return (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
}
And now the error returned is:
1>Memoization.obj : error LNK2005: "public: __cdecl Timer::Timer(void)" (??0Timer##QEAA#XZ) already defined in HelloWorld.obj
...
This is the main btw:
HelloWorld.cpp:
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#include "Memoization.cpp"
#include<vector>
#include"Utility.h"
using namespace std;
int main()
{
}
trying to define Utility.tpp: (RIGHT SOLUTION, FINALLY)
As in the comment made me notice, as an idiot I imported the Time methods in the .tpp file, and obviously I should have imported the templates function, and so in Utility.tpp contains print_tuple while Utility.cpp contains the 3 Timer functions.

If you are going to include a cpp file into a header file then you need to exclude that cpp file from compiling in the project. If you do not then the header file will have what the cpp file has and when the compiler compiles the cpp file into an object you will have two copies of the of the definitions. One in the header file as it has a copy of the cpp file in it and one in the cpp file as that is what is actually compiled. This leads to the redefinition errors.
Once you remove Utility.cpp from being compiled then any other cpp file that includes Utility.h will have a copy the full source since Utility.cpp is also included.
To remove Utility.cpp from compiling see: How to exclude files from Visual Studio compile?
If the only reason you are using a cpp file is because tpp files do not format C++ code as C++ then you can just configure MSVS to treat tpp files as C++ files. If you go to Tools -> Options -> Text Editor -> File Extensions you can add a file extension to the formatting. Enter the extension in the extension box, select Microsoft Visual C++ from the editor drop down and then click add.
Now you can use a tpp file instead of a cpp file and you do not have to remember to exclude the cpp file from the build. You also get to conform to modern practices.

There are main two problems:
You have placed intended header code in a ".cpp" file, which your IDE by default will treat as a main source code file (translation unit).
You are including non-inline function definitions (the class member functions) in the global namespace in a header. When that header is included in two or more translation units you will get a One Definition Rule (ODR) violation. In practice the linker will complain.
To fix this:
Change the filename extension from ".cpp" to e.g. ".hpp" or just plain ".h". It is code intended for header file use. The filename extension should reflect that, instead of misleading.
Declare the functions inline, or place definitions within the class definition.
In other news, possibly one of the <chrono> clocks, from the standard library, will serve your purpose so that you don't have to include <windows.h> in a header. It does drag in a zillion unreasonable macros. Including, by default, lowercase min and max macros, so this code is very ungood as given.

Remove the #include "Utility.cpp" line from Utility.h.
Then compile the Utility.cpp again

Related

Is it safe to separate your templated class' declaration and definitions on different header files?

I'm trying to create a library for a school work, and I've been wondering if it is safe to declare a templated class on the main header file containing the class definition and method declarations, but then separating the method definitions in a different header file?
Because I have been able to do this in my example below, but I don't know if it will cause me some problems in the long run.
main program
// main.cpp
#include <iostream>
#include "declaration.hpp"
int main()
{
card<int> a(5);
std::cout<<a.getID()<<'\n';
return 0;
}
main header file
in this header file, only the class definition and the declaration of the method getID() is written but not it's definition, and by the end of the class I included the other header file that contains the method definitions.
// declaration.hpp
#ifndef DEC_HPP
#define DEC_HPP
#include <iostream>
template<typename T>
class card
{
public:
T id;
card(const int id) : id(id) {}
T getID();
};
#include "definition.hpp"
#endif
method definitions
This header file contains the method definition of getID() from the main header.
I also included the "declaration.hpp" in this header, and this is the part where I'm not so sure of, because I included both files together with each other.
// definitions.hpp
#ifndef DEF_HPP
#define DEF_HPP
#include <iostream>
#include "declaration.hpp"
template<typename T>
T card<T>::getID()
{
return id;
}
#endif
I have compiled this program and it's working on my machine, but I just wanted to know if this way of isolating my code will cause me some errors in the future, I don't want to put my templated class definitions in a cpp files because I find it hard to maintain.
This is indeed a better approach because it makes your code look simple and better. Moreover, it is the main reason why header file is used.
Your main header file will simply tell that what functions/classes are you using and without even viewing your code, anyone can guess if you are working correctly or not.
There wont be any safety issues at all.

I'm getting a "redefinition of" error for every method in the class

I'm getting a redefinition error for every method in the class. I tried to put the .cpp code in the header where the "include Algebra.cpp" is, but didn't change a thing.
// This is the .h file
#ifndef ALGEBRA_H
#define ALGEBRA_H
#include <iostream>
template <size_t rows, size_t cols>
class Matrix {
double** matrix;
void debug_print();
public:
Matrix();
Matrix(double (&_matrix)[rows][cols]);
~Matrix();
double calculate_determinant();
};
#include "Algebra.cpp"
#endif
// This is the .cpp file
#include "Algebra.h"
#include <cassert>
template <size_t rows, size_t cols>
Matrix<rows, cols>::Matrix() {...}
// I have defined all the methods below..
First, that template function definition belongs in the header file that gets pulled in wherever it's needed with #include "algebra.h".
The reason you're getting problems with this particular setup is that, as several comments have suggested, you're compiling the .cpp file that contains that template function definition. When the compiler compiles "algebra.cpp", it first sees the #include directive at the top of the file, and pulls in the text from "algebra.h". That's fine as far as it goes, but at the end of "algebra.h" it sees #include "algebra.cpp". So it pulls in the text from there.
Now it's compiling "algebra.cpp" inside of "algebra.cpp". The include guard in "algebra.h" works here, so there is no redefinition of the contents of "algebra.h". And then it sees the definition of Matrix<rows, cols>::Matrix(). Still okay, so far.
Now it comes to the end of the code that comes in through the #include directive, so it continues to compile the code in "algebra.cpp", and it again sees the definition of Matrix<rows, cols>::Matrix(), and that's the redefinition that the compiler is complaining about.
That's why you shouldn't do that.
Some folks like to put definitions of member functions of class templates in a separate file from the header that defines the class template. That's okay, but don't compile that file; it should only be compiled as part of the header that uses it. And as a practical matter, that means giving it an extension that makes it clear that it's not a source file to be compiled on its own. When I've used that approach, I use ".inl" as the extension. If you change the name of "algebra.cpp" to "algebra.inl" and make sure that you're not telling the compiler to compile "algebra.inl" this problem should go away.

If you include something in the .h file Do you have to include the same thing again?

So I am just wondering if you #include something in a for example header.h file:
For example this is called header.h:
#include <vector>
#include <iostream>
#include <somethingElse>
So if for example I make a file called something.cpp Do I need to put all those include statements again?
#include "header.h"
// If I include #header.h in this file. Do the #include carry over to this file. Or do they not
I am wondering because whenever I include <vector> something in my .h file the #include statements that I used previously in the .h file always turn grey which means they are not used. Is it because I used it in the .h file? Its not a problem or anything I am just curious.
You don't need to include those headers again because your compiler can find those headers. You can also try to read and understand the makefile (or CMakeList) which will help.
Try always to avoid "Multiple file inclusion" via using inclusion guard or #pragma once in order to prevent the multiple file inclusion.
To include file means that the content of the file will be added to the very place you wrote include.
Here's an example:
// header.h
const int vlaue = 10;
const int value2 = 0;
// main.cpp
#include "header.h"
#include "header.h"
Above the content of "header.h" is added twice to main.cpp.
Do you know what is the result? It's a compile-time error complaining of redefinition of value and value2.
In the above example I think green programmers don't get trapped by it but it is just an explanation, So what I talk about is when a huge program where many header files and many source files and some files include others then it'll be so difficult to track the right file inclusion.
The workaround that is to use inclusion guards or pragma once eg:
Let's modify our header.h to look like:
// header.h
#ifndef MY_HEADER_H
#define MY_HEADER_H
const int vlaue = 10;
const int value2 = 0;
#endif
Now in main.cpp:
#include "header.h"
#include "header.h"
#include "header.h"
The code above works fine and no duplicate of header content is added to main.cpp. Do you know why? It's the magic of Macro there. So at first time the pre-processor checks whether a macro has been already defined with the name MY_HEADER_H or not and for sure for the first time it is not defined so the content is added. The second and so on the condition fails because the macro is already defined thus the content of header.h will not be added to where it is called.
The draw back of inclusion guard is if you have a macro with same name as the inclusion guard thus it is already defined so the content will never be added (empty content). Thus you get a compile-time error:
value, `value2` undeclared identifiers.
The second solution is using pragma eg:
Let's modify our header.h file:
// header.h
#pragma once
const int vlaue = 10;
const int value2 = 0;
// main.cpp
#include "header.h"
#include "header.h"
The code above works correctly so no multiple inclusion of header.h That is because of the magic of pragma once: which is a non-standard but widely supported pre-processor directive designed to cause the current source file to be included only once in a single compilation. Thus, #pragma once serves the same purpose as include guards, but with several advantages, including: less code, avoidance of name clashes, and sometimes improvement in compilation speed.
Finally you should include header wherever their content is used eg:
// Shape.h
class Shape{
// some code here
};
// Cube.h
#include "Shape.h"
class Cube : public Shape{
// some code here
};
// Cuboid.h
// #include "Shape.h"
#include "Cube.h" // So here the Shape.h is added to Cube.h and Cube.h is added here.
class Cuboid : public Cube{
// some code here
};
As you can see above the content of Shape.h is added to Cuboid.h indirectly because it is added to Cube.h and cuboid.h includes Cube.h so it is added to it. So without inclusion guards or pragma once if you include the two headers in one source file you get duplicate content there.

gcc - multiple definition error when defining template (vc++ fine)

I'm using EnumParser from here It compiles fine in VC++, but using gcc I have such error:
./Terminator.o: In function `EnumParser<FieldType>::EnumParser()':
Terminator.cpp:(.text+0x960): multiple definition of `EnumParser<FieldType>::EnumParser()'
./MicexGate.o:MicexGate.cpp:(.text+0xd0): first defined here
./Terminator.o: In function `EnumParser<FieldType>::EnumParser()':
Terminator.cpp:(.text+0x960): multiple definition of `EnumParser<FieldType>::EnumParser()'
./MicexGate.o:MicexGate.cpp:(.text+0xd0): first defined here
./Terminator.o: In function `EnumParser<FieldsetName>::EnumParser()':
It seems EnumParser<FieldType>::EnumParser() appeared in both MicexGate.o and Terminator.o and this is the problem. But i don't know why this is an error and how to fix it.
In my program I define this EnumParser just once in .cpp file in MicexGate static lib project. Terminator depends on MicexGate probably that's why finally EnumParser defined twice. This is how I define EnumParser<FieldType>:
#include "FieldsConverter.h"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
#include "ByteArrayReader.h"
#include "Utils.h"
#include "CommonsMicexBridge.h"
#include "InstrumentsStorage.h"
#include <boost/algorithm/string.hpp>
template<> EnumParser<FieldType>::EnumParser()
{
enumMap["Char"] = Char;
enumMap["Integer"] = Integer;
enumMap["Long"] = Long;
enumMap["Fixed"] = Fixed;
enumMap["Price"] = Price;
enumMap["Date"] = Date;
enumMap["Time"] = Time;
}
How can I fix my problem?
My guess is that you haven't declared the explicit specialisation in a header, included in every file that uses the specialisation:
template<> EnumParser<FieldType>::EnumParser();
Without this declaration, the compiler doesn't know that the explicit specialisation exists, so will instantiate an implicit specialisation from the generic template if it needs one. You now have two definitions, resulting (hopefully) in a link error.
Alternatively, as with any function, you can define it in a header as long as you declare it inline to allow definitions in multiple translation unit.
Templates need to be in headers and not in .cpp files.

C++ Templates Declaration Order

I am trying to compile a minimal example which instantiates
a template class. The example compiles fine when a certain order
of declarations is kept, but fails otherwise.
temp.h:
#include <iostream>
template <bool display>
class test {
public:
void sayHi();
};
temp.cpp:
#include "temp.h"
template <bool display>
void test<display>::sayHi () {
if (display) std::cout << "Hi";
}
main.cpp:
#include <iostream>
#include "temp.h"
int main () {
test<true> myobject;
myobject.sayHi();
return 0;
}
This is the standard of how to include classes.
In GCC 4.4.6, this fails with the error
main.cpp:(.text+0x3a): undefined reference to `test::sayHi()'
However, the example compiles when I do a #include "temp.cpp" instead of #include "temp.h" in main.cpp
file, so that the compiler reads the class declaration in temp.h first, then
sees the content of temp.cpp and only afterwards the content of main.cpp.
When I use non-template classes, it works fine to include just .h files
in main.cpp -- what is going wrong here? Note that the temp.cpp is included
in my Makefile, so it definitely should not be forgotten by the compiler.
Thanks for any help.
See the C++ FAQ Lite entry [35.12] Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?.
The definition (aka body) of the sayHi() method must be in the temp.h header, or in another included file; the full code is needed when you instantiate test<true>.
With templates, both declaration and definition must be in the same file. You can do this by either putting all your code in one file (and making the function definitions inline or not, it's up to you), or making the declaration and definitions seperate, but including the definitions file at the bottom of the .h file.
So it would be
tmp.h:
#include <iostream>
template <bool display>
class test {
public:
void sayHi();
};
#include "tmp.cpp"
and tmp.cpp and main.cpp remain the same (but you don't give tmp.cpp to the compiler to compile since it's included by tmp.h).
Many people name the files that have template function definitions in them with a .template extension instead of .cpp extension (it lets you know it's not to be compiled, plus it looks less weird than including a .cpp file), but you don't have to.