Reputation: 55
I have this template class
MyTemplates.h
#ifndef MYTEMPLATES_H
#define MYTEMPLATES_H
#include <iostream>
#include "Main.h"
template <class T>
class myTemplates
{
T difference(T,T);
};
template <class T>
T myTemplates<T>::difference(T a,T b)
{
return t ((a.getX() - b.getX()),(a.getY() - b.getY()) );
}
Main.cpp
Point p_a (2, 8);
Point p_b (5, 10);
cout << endl;
cout << "difference (p_a, p_b) returns a point with value : ";
p = difference (p_a, p_b);
cout << p << endl << endl;
When i run this, i will get the error called, "differences were not declared in this scope". What i'm trying to do here is to pass two objects into the template and returns the differences in value. in my point class, i have a ostream operator that display the x and y ordinates
Upvotes: 1
Views: 143
Reputation: 4488
This answer is no longer relevant since the question has been edited
Template class used by another .cpp
file cannot be put in a .cpp
file.
The compiler doesn't know the type of T when compiling the .cpp
.
You must put everything that use the type T
inside the .h
This is fine if you put everything (the class and the implementation) into the .cpp
file, if this template class is used only in this .cpp
file.
Upvotes: 1
Reputation: 254431
You've made difference
a member of a class template, even though it doesn't logically belong to a class. You should make it a free function template:
template <class T>
T difference(T a,T b)
{
// whatever
}
and then your code in main
should work as you expect - the template parameter will be inferred from the function argument types.
If you did want it to be a class member, then you'll need an object to call it on:
p = myTemplates<Point>().difference(p_a, p_b);
but that's clearly not what you want here.
Upvotes: 3
Reputation: 708
The compiler needs a complete definition of a template to be able to instanciate it.
You have 2 translation units: myTemplates.cpp and Main.cpp. When compiling myTemplates.cpp actually nothing happens, because it's a template definition with no instantiation.
Then you compile Main.cpp and want to instanciate myTemplate, but this is not possible, because the definition of your template in myTemplates.h is not complete: a part of the template definition is in myTemplates.cpp and the compiler already forgot about that one ;)
To solve your problem you need to put the complete template definition into myTemplates.h and as myTemplates.cpp is then empty, you can get rid of it.
As your Main.cpp you posted is incomplete and you still get the error: don't forget to include myTemplates.h in your Main.cpp.
Upvotes: 0
Reputation: 14174
C and C++ compiles each sorce file is its own "translation unit". A translation unit is the sum of the sourcecode of the .cpp file and all files #include
d on it. So when you compile foo.cpp
and bar.cpp
, the compiler compiles each cpp file as if it was a hole independient program.
C++ templates compiles in two phases:
Declaration: The compiler parses the template declaration, checking its syntax and semantic correctness. Every statement dependent of a template argumment is not parsed here, is parsed in the second phase.
Instantation: For each template instantation, the compiler subsitutes the template parametes of the template with the type specified by the instantation, and parses the resulting sourcecode.
The problem with .cpp files is the compiler parses by translation units, but the header and the .cpp file are compiled in different translation units. It should execute the two phases of template parsing in the same translation unit (It needs the result of the first phase to execute the second phase), so when you use a template in the .cpp, the compiler does not know the result of the first phase, which was executed in the header file.
Upvotes: 0