Undefined reference from templated function (C++) [duplicate] - c++

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 10 years ago.
main.o: In function `main':
main.cpp:(.text+0x2f): undefined reference to `Foo<int>::display(int)'
collect2: ld returned 1 exit status
caused by
g++ -c *.cpp && g++ *.o -o foo
with foo.hpp:
#ifndef FOO_H_
#define FOO_H_
template<typename T>
class Foo {
private:
T ft_;
public:
Foo(const T & ft) : ft_(ft) { }
Foo display(T x);
};
#endif
foo.cpp:
#include "foo.hpp"
#include<iostream>
using namespace std;
template<typename T>
Foo<T> Foo<T>::display(T x) {
// do some stuff - not too relevant
cout << "[" << x << "]";
Foo<T> res(x);
return res;
}
and main.cpp:
#include<iostream>
#include "foo.hpp"
using namespace std;
int main() {
Foo<int> f(42);
Foo<int> g = f.display(39);
return 0;
}
Why?!
P. S. Works with inlined function definitions. Troubles come whenever declaration and definition of a function is split into two files...

In C++ you need to put the definition of templated methods and functions into the header file.

Related

Undefined reference to function of class [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 1 year ago.
I'm dealing with oop and cannot understand what is wrong. When i try to compile code i get next messsage: undefined reference to `N::my_class::do_something()'. Code is from microsoft: https://learn.microsoft.com/en-us/cpp/cpp/header-files-cpp?view=msvc-160
my_class.h file:
namespace N
{
class my_class
{
public:
void do_something();
};
}
my_class.cpp file:
#include "my_class.h" // header in local directory
#include <iostream> // header in standard library
using namespace N;
using namespace std;
void my_class::do_something()
{
cout << "Doing something!" << endl;
}
my_program.cpp file:
#include "my_class.h"
using namespace N;
int main()
{
my_class mc;
mc.do_something();
return 0;
}
Your code works for me on g++ 8.4.0.
using namespace N; might not enough to declare member function in N for your compiler.
Try to specify the namespace either inline or using a namespace scope in your cpp file.
EDIT: most likely problem. my_class.cpp is not compiled or linked. Check your compile parameters.

Defining static member of template class in a implementation file [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 4 years ago.
I simplify the problem. I wanna know why this can't compile:
Error message: undefined reference to 'Foo<int>::j'
a.h
#pragma once
template<typename T>
class Foo{
public:
int bar(){
return j;
}
private:
static int j;
};
a.cpp
#include "a.h"
template<typename T>
int Foo<T>::j = 3;
main.cpp
#include "a.h"
#include <iostream>
using namespace std;
int main() {
Foo<int> f;
cout << f.bar();
return 0;
}
Templates are the cause.
template<typename T>
int Foo<T>::j = 3;
doesn't get resolved for main.cpp as it has no information about a.cpp.
And as for a.cpp it doesn't create Foo as it isn't used there.
For the system to work, you'd need to add
int Foo<int>::j = 3;
to a.cpp or
template<typename T>
int Foo<T>::j = 3;
to main.cpp.
On the side note, maybe new usage of inline keyword in C++17 i what you are looking for.

I have three cpp file.I want test that template class declaration and definition in different file.but i got failed [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Storing C++ template function definitions in a .CPP file
(13 answers)
Closed 4 years ago.
this is my code snnippet
// test.cpp
#include <iostream>
#include "test.h"
int main(){
Test<int> test = Test<int>();
test.add(1);
test.print();
}
// test.h
#ifndef TEST
#define TEST
template <typename T> class Test{
public:
T info;
void print();
void add(T i);
};
#endif
// testT.cpp
#include <iostream>
#include "test.h"
template<typename T> void Test<T>::print()
{
std::cout << info << std::endl;
}
template<typename T> void Test<T>::add(T i)
{
info = i;
}
and i run this exec
g++ -c testT.cpp && g++ test.cpp -o a.out testT.o
i get this error
Undefined symbols for architecture x86_64:
"Test<int>::add(int)", referenced from:
_main in test-e89092.o
"Test<int>::print()", referenced from:
_main in test-e89092.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation) // in my macOS
i want to declare template class in head file and define method in other file,so i only compile the define method file not head file if i change the definition of method in template class. what should i do?
A posible way to seperate template to cpp and header is to typedef it to the types you are using it from the source which define the functions bodies.
for example: in your code, if you'll add a typedef Test<int> __UNUSED_TEMP_INT__; in the bottom of testT.cpp it will compiled for int in a place it recognize the bodies. but than you can use the template only for int.
Other option is to include the source from the header, but then the cpp is just another header.

I have included a template function declaration in a header file and the defintion of the function is written in the .cpp file [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Storing C++ template function definitions in a .CPP file
(13 answers)
Closed 5 years ago.
I have declared a template function in .h file and defined in a .cpp file and calling the function from another .cpp file.
i am getting the following error
/tmp/ccJg5vwy.o: In function main':
main.cpp:(.text+0x8f): undefined reference toshort temp < int, std::allocator < int > >(std::__cxx11::list > const&)'
collect2: error: ld returned 1 exit status
my files are:
//main.cpp
#include"a.h"
#include<iostream>
#include<list>
using namespace std;
int main(){
list<int> arr(5);
for (int i=0;i<5;i++)
arr.push_back(i);
fun1();
fun2();
temp(arr);
return 0;
}
//a.h
#include <list>
using namespace std;
void fun1();
void fun2();
template <class L ,class A>
short temp(const list<L,A>& val);
//fun2.cpp
#include"a.h"
#include<iostream>
using namespace std;
void fun2(){
cout<<"I am in function2\n";
}
//a.cpp
#include "a.h"
#include<iostream>
using namespace std;
void fun1()
{
cout<<"I am in function1\n";
}
template <class L,class A>
short temp(const list<L,A>& val){
cout<<"inside the template function\n";
typename list<L,A>::const_iterator iter=val.begin();
while (iter != val.end())
{
cout<< *iter << endl;
++iter;
}
cout<<"leaving the template function\n";
return 0;
}
and i am compiling the files in the following format
g++ a.cpp fun2.cpp main.cpp
I am not getting why there is a linking problem.
I have also tried by changing a.cpp and a.h to the following format but still i am getting the error
//a.cpp
#include "a.h"
#include<iostream>
using namespace std;
void fun1()
{
cout<<"I am in function1\n";
}
template <class L>
short temp(const list<L>& val){
cout<<"inside the template function\n";
typename list<L>::const_iterator iter=val.begin();
while (iter != val.end())
{
cout<< *iter << endl;
++iter;
}
cout<<"leaving the template function\n";
return 0;
}
//a.h
#include <list>
using namespace std;
void fun1();
void fun2();
template <class L>
short temp(const list<L>& val);
in this case error is
/tmp/cce0eJj9.o: In function main':
main.cpp:(.text+0x8f): undefined reference toshort temp< int >(std::__cxx11::list > const&)'
collect2: error: ld returned 1 exit status

undefined reference to `std::ostream& SpyOutput::operator<< <double>(double const&)'

I'm trying to intercept "the data" from standard output (for this question I'm working with cout). Also for this question I'm working with double, but the program should be able to handle any primitive data type. When I try to compile my code I get this error:
undefined reference to `std::ostream& SpyOutput::operator<<
(double const&)' collect2: error: ld returned 1 exit status
this is my main:
#include "SpyOutput.h"
#define endl '\n'
int main ( int argc, char *argv[], char *env[] ) {
double d1 = 12.3;
SpyOutput spy(&cout);
spy << d1;
return 0;
}
this is my header file:
#include <iostream>
using namespace std;
class SpyOutput {
private:
ostream* output;
public:
SpyOutput(ostream* os);
template <class T>
ostream &operator<<(const T &x);
};
this is my implementation file:
#include "SpyOutput.h"
SpyOutput::SpyOutput(ostream* os){
output = os;
}
template <class T>
ostream& SpyOutput::operator<<(const T &x){
// SOME CODE GO HERE
return *output;
}
I have googled this error (and similar) without finding a working solution, thanks in advance for any help or hint that you can provide to me! :-)
What's the problem?
For an explanation why it doesn't compile, see "Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?"
As an example, consider the header file foo.h which contains the following template function declaration:
// File "foo.h"
template<typename T>
void foo();
Now suppose file foo.cpp actually defines that template function:
// File "foo.cpp"
#include <iostream>
#include "foo.h"
template<typename T>
void foo()
{
std::cout << "Here I am!\n";
}
Suppose file main.cpp uses this template function by calling foo():
// File "main.cpp"
#include "foo.h"
int main() { foo<int>(); ... }
If you compile and link these two .cpp files, most compilers will generate linker errors. Because in order for the compiler to generate the code, it must see both the template definition (not just declaration) and the specific types/whatever used to "fill in" the template. If the template body is defined in the .cpp the compiler won't see it and hence won't generate any code for it.
How to fix it?
There is more than one possible solution around this issue. I suggest moving the definition of the template function into the .h file.
// File "foo.h"
template<typename T>
void foo()
{
std::cout << "Here I am!\n";
}
In your source you can call it as usual:
// File "main.cpp"
#include "foo.h"
int main() { foo<int>(); ... }
You need to place your template implementation of SpyOutput::operator<< into the header file