I am trying to get a template code working with the header file and cpp file separated. I use explicit instantiation for this. But I still get an undefined reference error.
foo.h
template<typename T>
class Foo
{
public:
void f();
};
foo.cc
#include <iostream>
#include "Foo.h"
template<typename T>
void Foo<T>::f()
{
std::cout << "Foo<T>::f()\n";
}
template class Foo<int>;
main.cc
#include "foo.h"
int main()
{
Foo<int> x;
x.f();
}
When I compile:
g++ main.cc -o test
/tmp/ccfHjiVJ.o: In function `main':
main.cc:(.text+0x10): undefined reference to `Foo<int>::f()'
collect2: ld returned 1 exit status
The gcc version I use is gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
You've forgotten to compile foo.cc in your compile command, add foo.cc:
g++ main.cc foo.cc -o test
^^^^^^
Related
I'm trying to define a simple explicit conversion in C++11, separately from the header file, using GCC 4.8.5 (CentOS 7's default):
foo.h:
#ifndef foo_h_
#define foo_h_
typedef struct {
int x;
explicit operator int() const;
} A;
#endif
foo.cpp:
#include "foo.h"
A::operator int() const
{
return this->x;
}
main.cpp:
#include "foo.h"
int main(int,char**)
{
A a{1};
int b = (int)a - 1;
return 0;
}
GCC 4.8.5 inexplicably fails to link this code:
$ g++ -std=c++11 foo.cpp main.cpp
/tmp/cc5osctA.o: In function `main':
main.cpp:(.text+0x1e): undefined reference to `A::operator int() const'
collect2: error: ld returned 1 exit status
However, if I use any version of GCC >= 5 (e.g. GCC 5.3.1 from RHEL's devtoolset-4 software collection), it works, as I'd expect it to:
$ scl enable devtoolset-4 "g++ -std=c++11 foo.cpp main.cpp"
### (no linker errors, b == 0 when running)
Is this a bug in GCC 4.8.5's C++11 support? Or is my code malformed?
i have this simple code in the following files:
Stat.h
#ifndef STAT_H
#define STAT_H
class Stat {
public:
void compute_value();
};
#endif
Stat.cpp
class Stat {
public:
void compute_value() {
}
};
main.cpp
#include "Stat.h"
int main(void)
{
Stat stat;
stat.compute_value();
}
When i try to compile i got the following error:
clang++ -std=c++14 -Wall -Wextra -pedantic -Weverything -O3 Stat.cpp main.cpp -o main
/tmp/main-0466d7.o: In function `main':
main.cpp:(.text+0xf6a): undefined reference to `Stat::compute_value()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
You are redefining the class in your Stat.cpp source file because definition is also a declaration. Instead of having the entire class redefinition you only need to define the member function(s) in your Stat.cpp source file and include the Stat.h header:
#include "Stat.h"
void Stat::compute_value() {}
Consider a program consists of files AA.hpp, A1.hpp, A1.cpp, and main.cpp compiled with g++ -std=c++11 main.cpp A1.cpp.
// file AA.hpp
template < int > struct AA;
// file A1.hpp
#include "AA.hpp"
template <> struct AA<1> { /*implementation goes here...*/ };
extern template struct AA<1>;
// file A1.cpp
#include "A1.hpp"
template struct AA<1>;
// file main.cpp
#include "A1.hpp"
int main()
{
AA<1> a1;
// use a1 ...
return 0;
}
Compare this with a scenario when there is no A1.cpp and there is no explicit instantiation declaration in A1.hpp. Will I get any compilation time benefits in the first scenario? And why?
Another question. What if I make a shared library of A1.cpp by g++ -std=c++11 -shared -o libA1.so A1.cpp and then make executable with g++ -std=c++11 -lA1 main.cpp? Will the calls of A1's functions in man.cpp refer to the code in libA1.so or they will be generated (inlined or not) in the executable?
I'm using Dev-C++ 5.2.0.1
I took an example of how to put a class in another file from a website but it resulted in an error.
In the file class.h I have:
class MyClass
{
public:
void foo();
int bar;
};
In the file class.cpp I have:
#include "class.h"
void MyClass::foo()
{
cout<< "test";
}
In the file main.cpp I have:
#include "class.h"
using namespace std;
int main()
{
MyClass a;
a.foo();
return 0;
}
Here is the error I get:
[Linker error] C:\Users\Matthew\AppData\Local\Temp\cccWe7ee.o:main.cpp:(.text+0x16): undefined reference to `MyClass::foo()'
collect2: ld returned 1 exit status
Is there something I'm doing wrong?
New answer.
Are you compiling and linking all of your files together? In gcc you would do something like:
gcc -o myExe class.cpp main.cpp
I'm not so sure about dev-c++, but I imagine it's not much different.
foo() only have definition. If you want to use a function that doesn't have a implement, Linker will give you this error "undefined reference".
class.h
#include <iostream>
#include <stdint.h>
using namespace std;
template <typename T>
class CIntegerType {
public:
void Show ( void );
private:
T m_Data;
};
class.cpp
#include "class.h"
template <typename T>
void CIntegerType<T> :: Show ( void ) {
cout << m_Data << endl;
}
main.cpp
#include "class.h"
int main ( void ) {
CIntegerType<uint32_t> UINT32;
UINT32 . Show ();
return 0;
}
This commands return:
g++ -Wall -pedantic -c main.cpp
g++ -Wall -pedantic -c class.cpp
g++ -Wall -pedantic -o class.o main.o
main.o: In function `main':
main.cpp:(.text+0x11): undefined reference to 'CIntegerType< unsigned int>::Show()'
collect2: ld returned 1 exit status
Try putting your template implementation in the header file.
See: Why can templates only be implemented in the header file?
Try g++ -Wall -pedantic -o main.o class.o instead. You are facing the same problem as in this question: g++ linking order dependency when linking c code to c++ code
The linker searches for functions in the order they appear. Since you have a template function, its use in main must be fed to the linker prior to the actual code to instantiate it in class.