I am trying to understand how templates work, if we are talking about putting them in separated files. I would like to create class with templates, precisely I would like now to create a Conversion class, with the usual <sstream> and its classes.
I have read some post about the topic, and apparently one solution is this:
write the template declaration in a header file, then implement the class in an implementation file (for example .tpp), and include this implementation file at the end of the header.
But this seems almost a infinite loop, of course it isn't: the header file includes the source file and the source file has to include the header file.
When we include one file all the contents are copied (if I am not wrong), so it seems not a good idea, especially if the class is very large.
Can you dudes explain me what you know about how to create a template class and implement its methods in a source file?
Maybe with examples I can delete[] all the doubts from the memory.
tpp is not a source file like cpp. It is an arbitrary file extension, so that the compiler does not treat it like a cpp file.
The point of doing this is to merely extend the header file, but that extension is hidden in another file. Remember that when you include a header, the preprocessor merely pastes the code from the header into the destination.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
//funky.h
#ifndef HI
#define HI
template <typename Bar>
void funky(Bar);
#include "funky.tpp"
#endif
//funky.tpp
#include <iostream> //Notice we don't include funky.h
template <typename Bar>
void funky(Bar b)
{std::cout << b;}
After including, the header file becomes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//funky.h
#ifndef HI
#define HI
template <typename Bar>
void funky(Bar);
#include <iostream>
template <typename Bar>
void funky(Bar b)
{std::cout << b;}
#endif
So it is just like we would put the definition in the header file, but this way, we "hide" the implementation.
And if we have to declare for example a class, in a header file, which includes an #include <string>, and in the source file that extends this last one is also included the <string>, what would happen? what can we do to solve this?
If we are talking about classes and static methods, how would be the simple solution?
If you are worried about multiple copies of your .tpp code (because for some reason you would need to include them in multiple places), you can wrap their code in include guards as well.
/*
Conversion.tpp
*/
#pragma once
#include <string>
#include <sstream>
using std::string;
using std::istringstream;
using std::ostringstream;
//converts any number to string
template <typename T>
string Conversion<T>::NumberToString(T number)
{
ostringstream oss;
oss << number;
return oss.str();
}
//converts strings to any number speficied
template <typename T>
T Conversion<T>::StringToNumber(const string &str)
{
istringstream iss(str);
T number;
return (iss >> number)? number : 0;
}
------------------------------------------------------------------------------------ ERROR: Conversion.o: No such file or directory
=>
$(BIN): $(OBJ)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)