Error Even after Explicit Instatantiation - c++

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

Defining explicit conversion - possible GCC bug

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?

failed to link simple code

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() {}

Will extern template reduce the compile time for a full specialization?

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?

creating classes link error

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".

C++ linking object's files (G++)

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.