Templated Member Functions instantiation

I obtained a .hpp file online which contained both the class declaration and definition together as such:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Foo.hpp

class Foo{
  Foo();
  
  <template T>
  Foo& func1(const &T t);
};

inline Foo::Foo(){
  //constructor
}

<template T>
Foo& Foo::func1(const T& t){
     //function 
}


I have to include this header file (basically a library) in multiple source files. Since it contains the definitions of the methods, I get redeclaration errors. So I decided to split the definitions into a .cpp file and I'm using the library in main.cpp as shown.

1
2
3
4
5
6
7
8
//Foo.hpp

class Foo{
  Foo();
  
  <template T>
  Foo& func1(const T& t);
};


1
2
3
4
5
6
7
8
9
10
11
12
//Foo.cpp
include "Foo.h"


Foo::Foo(){
  //constructor
}

<template T>
Foo& Foo::func1(const T& t){
     //function 
}


1
2
3
4
5
6
7
8
9
10
11
//main.cpp

#include "Foo.h"

int main (void){

  Foo bar;
  bar.func1(5);  //shows error as "undefined reference to"
  bar.func1<int>(5); //doesn't work either

}



From what I've found, I think that the acceptable types for the template should be declared by instantiating the template. However I don't know the syntax and the location to do so. Thanks in advance for any assistance.

UPDATE: just as a temporary workaround, I have explicitly stated the argument types as "int" for func1() in both the prototype in Foo.hpp and definition in Foo.cpp and getting rid of the template all together. No errors returned.

This is just temporary as there are many other similar templated functions as func1() and it does not seem like a pretty way to solve the issue. I strongly believe that "int" should be declared as one of the data types for template T, i just don't know how.
Last edited on
I get redeclaration errors

what do the error messages say, exactly? Does it says "multiple definition of `Foo::Foo()'"? If so, why are you concerned with templates?

Foo::func1 is a template function, its definition belongs in the header.

Foo::foo, on the other hand, is not a template and you could put it in a source file if you so wish, although I see no benefit in doing so, unless there is code you're not showing. To keep Foo::Foo in the header you need to either define it inside the class definition or use the much misunderstood keyword inline with its definition: inline Foo::Foo() {}
Last edited on
Ok, i have edited the original .hpp file in the question. It originally included the inline keyword with its definition. I also mistakenly put the template with the wrong method initially, i corrected the typo.

After splitting the file into Foo.hpp and Foo.cpp, the constructor call in main.cpp returned a "undefined reference to" error, removing the inlinse keyword solved that issue.

However i still have errors on func1 calls, it shows "undefined reference to Foo& Foo::func1<int>(int)"
Last edited on
First, get your code sample working as it is supposed to, before it's ruined by "splitting"


~$ cat Foo.hpp
class Foo{
 public:
  Foo();
  
  template<class T>
  Foo& func1(const T& t);
};

inline Foo::Foo(){
  //constructor
}

template<class T>
Foo& Foo::func1(const T& t){
     //function 
     return *this;
}
~$ cat main.cpp
#include "Foo.hpp"
void x();
int main()
{
    Foo f;
    f.func1(1);
    f.func1(0.1);
    x();
}
~$ cat test2.cpp
#include "Foo.hpp"
void x()
{
    Foo f;
    f.func1('a');
}
~$ g++ -Wall -pedantic -o test main.cpp test2.cpp
~$ ./test
~$


What actual code produced the error messages you described?
Topic archived. No new replies allowed.