Reputation: 984
EDIT: This is NOT a duplicate of the standard templating questions.
My scenario involves a templated class and a member function of that class whith one argument that is templated, but not of the same type as the class.
Even when I put the definition in the header I still can't find the correct syntax.
Can someone help me with my specific question?
My oversimplified code:
Foo.h:
template<typename T1>
class Foo {
public:
template<typename T2>
static void bar(vector<T1>& a, vector<T2>& b);
};
Foo.cpp:
#include <Foo.h>
template<typename T1>
template<typename T2>
void Foo<T1>::bar(vector<T1>& a, vector<T2>& b) {
//code logic
}
Goo.cpp:
#include <Foo.h>
int main(int argc, char** argv) {
vector<int> a;
vector<double> b;
Foo<int>::bar(a, b);
}
My error:
undefined reference to
void Foo<int>::bar<double>(std::vector<int, std::allocator<int> >&,
std::vector<double, std::allocator<double> >&)
I couldn't find the proper way to define the templates.
I also noticed that the order of the typenames will change the error (also putting the entire function in the class declaration).
What is the correct syntax?
Upvotes: 1
Views: 53
Reputation: 1192
Your problem is not in the declarations or definitions. The problem is the splitting of definition and declaration. That doesn't work the way you are doing it. When compiling foo.cpp
, no uses of your template are visible, and so there will be no instances created. When compiling goo.cpp
, the linker will therefore not be able to link to them.
Thats what this error means:
undefined reference to 'void Foo<int>::bar<double>(std::vector<int, std::allocator<int> >&, std::vector<double, std::allocator<double> >&)'
If you really want to do what you are doing, you need to use explicit instantiation for every combination of types.
Change foo.cpp
to this (note the explicit instantiation definition in the last line):
template<typename T1>
template<typename T2>
void Foo<T1>::bar(std::vector<T1>& a, std::vector<T2>& b) {
//code logic
}
template void Foo<int>::bar(std::vector<int>&, std::vector<double>&);
Upvotes: 1