1

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?

Nimrod Morag
  • 938
  • 9
  • 20
  • Why do you think this is not a duplicate? You cant define templates in the source file. "Even when I put the definition in the header I still can't find the correct syntax." ...then why dont you show the code with the definition in the header? – 463035818_is_not_an_ai Sep 04 '17 at 15:04
  • If you [edit] the question to show us the code with the templated member function defined in the header file, we can reopen it. Kudos for simplifying your code - do make sure the edited simplified version still fails, and include the error message. (If you @-mention me in a comment, I think I can reopen it single handedly.) – Martin Bonner supports Monica Sep 04 '17 at 15:13
  • Your Foo.h has a typo and a missing semicolon. Please only copy and paste code you have actually tried to compile and verified that you get the claimed error message. – aschepler Sep 05 '17 at 23:32

1 Answers1

1

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>&);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
DrSvanHay
  • 1,170
  • 6
  • 16