This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 8 years ago.
The question is how to call the base constructor from an inherited template class. I want to create a FixedQueue and overload some function in std::queue. Therefore std:queue is the base class. The keyword using, since c++11, can be used to call the base and it works if this is a specialised class, but I cannot get it working with a template class.
Furthermore I tried it to use the old c++ standard in which I simply invoke the defined constructors in std::queue. However it doesn't work.
h file
#ifndef _HEADER_FIXED_QUEUE_
#define _HEADER_FIXED_QUEUE_
#include <queue>
#include <iostream>
template<class T>
class FixedQueue : public std::queue<T>
{
//using queue<T>::queue<T>;
public:
FixedQueue();
FixedQueue(const T &initial_var);
void foo() { std::cout << "inside\n"; }
};
#endif
cpp file
#include "FixedQueue.h"
template<typename T>
FixedQueue<T>::FixedQueue()
:
std::queue<T>()
{
std::cout << "Default Constructor FixedQueue\n";
}
template<typename T>
FixedQueue<T>::FixedQueue(const T &initial_var)
:
std::queue<T>(initial_var)
{
std::cout << "Specialized Constructor FixedQueue\n";
}
main file.
#include <iostream>
#include "FixedQueue.h"
int main()
{
FixedQueue<int> d_frameSlices;
std::cout << "I want to do something with my queue\n";
}
The question is thus. How do I chain the constructors to the defined constructors in the base class std::queue. The template thing is killing me.
This is the error message I obtain from clang, which is the usual undefined reference.
Undefined symbols for architecture x86_64:
"FixedQueue<int>::FixedQueue()", referenced from:
_main in main-lqoFSA.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
If someone knows how to do this with "using" or the old fashion way I am happy with both. Thanks in advance
you should not put the template in cpp file put it all in header file
Related
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 4 months ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
Defining a class with the template generics is not letting me compile this class.
I have the following three files:
Class Definition:
#ifndef _myclass_h
#define _myclass_h
template <typename ValueType>
class myClass {
public:
myClass();
};
#endif
Class Implementation:
#include "myClass.h"
template <typename ValueType>
myClass<ValueType>::myClass() { }
And the test file:
#include "myClass.h"
int main() {
myClass<int> cls;
return 0;
}
I'm compiling it on a MacBook Air (M1, 2020) running a MacOs Big Sur version 11.6 (20G165).
And when running this command:
g++ -std=c++11 -o testMyClass myClass.cpp testMyClass.cpp
I'm getting this error:
Undefined symbols for architecture arm64:
"myClass<int>::myClass()", referenced from:
_main in testMyClass-595230.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [testMyClass] Error 1
It seems that for some reason the compiler is not able to find the class constructor definition in myClass.cpp. If I take the template header in all of the classes and make the proper adaptations, the class is compiled.
Does anyone have a clue on how to solve that?
I was able to implement the idea suggest here by doing the following.
In myClass.cpp I commented out the inclusion, ending up with:
/* #include "myClass.h" */
template <typename ValueType>
myClass<ValueType>::myClass() { }
And included myClass.cpp to myClass.h, like this (last line):
#ifndef _myclass_h
#define _myclass_h
template <typename ValueType>
class myClass {
public:
myClass();
};
#endif
#include "myClass.cpp"
Aesthetically, I consider this to be an ugly solution, but it works.
This question already has answers here:
Separating class code into a header and cpp file
(8 answers)
Closed 5 months ago.
I don't know how to add functions of a class outside its scope to it, use them in another class and then compile it.
MyMain.cpp
#include"MyClass.cpp"
int main(){
MyClass myClass;
myClass.run();
}
MyClass.cpp
#ifndef MYCLASS_CPP
#define MYCLASS_CPP
#include<iostream>
class MyClass {
private:
void usage();
public:
void run();
};
void MyClass::usage(){
std::cout << "usage called" << std::endl;
}
void MyClass::run(){
usage();
}
#endif
I try to compile it with:
g++ MyMain.cpp MyClass.cpp -o main
With that I get the following error message:
/usr/bin/ld: /tmp/ccN7GfOD.o: in function `MyClass::usage()':
MyClass.cpp:(.text+0x0): multiple definition of `MyClass::usage()'; /tmp/ccLhxS6v.o:MyMain.cpp:(.text+0x0): first defined here
/usr/bin/ld: /tmp/ccN7GfOD.o: in function `MyClass::run()':
MyClass.cpp:(.text+0x38): multiple definition of `MyClass::run()'; /tmp/ccLhxS6v.o:MyMain.cpp:(.text+0x38): first defined here
collect2: error: ld returned 1 exit status
If I have understood the concept correctly, the function headers within the class serve only as placeholders. The actual functionality is then "overwritten" by the external functions, which also contain a body.
And why does the error message say, that the function is already defined in the MyMain.cpp?
I have also seen that there are many similar questions here, but unfortunately I could not expand my understanding of the basic problem to solve it.
Is it possible that I am using the command to build the class with C++ incorrectly or that I can save the #include "MyClass.cpp"?
Kind regards
Several things wrong. here's the steps to put it right
Rename MyClass.cpp to MyClass.h.
Create a new empty file MyClass.cpp
Move the function definitions MyClass::usage() { .. } and MyClass::run() { .. } from MyClass.h to MyClass.cpp. You should probably also move #include <iostream> but this is not essential.
Add #include "MyClass.h" to MyClass.cpp
Change #include "MyClass.cpp" to #include "MyClass.h" in MyMain.cpp
Then build as you are doing now. That part is correct.
Essentially the technique is to separate your code into declarations and definitions. The declarations go into header files, which are included in the cpp files. The cpp files contain the definitions and are what you compile.
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Static member initialization in a class template
(3 answers)
Closed 4 years ago.
Let's say for some reason, I want to have a class template MyTemp with some static data member smDummyVar :
Mytemp.h
#ifndef MY_TEMP_H
#define MY_TEMP_H
template<class T>
class MyTemp{
...
private:
static int smDummyVar;
...
};
#include "MyTemp.cpp"
#endif //MY_TEMP_H
Mytemp.cpp
...
template<class T> int MyTemp<T>::smDummyVar = 0;
...
Since the compiler requires that the definition and declaration of a template be at the same place, so I include MyTemp.cpp in MyTemp.h .
Now: I want to use MyTemp at many places and create objects using the template:
case1.cpp
#include "MyTemp.h"
void dummyfunc1(){
MyTemp<int> myTemp1;
}
case2.cpp
#include "MyTemp.h"
void dummyfunc2(){
MyTemp<int> myTemp2;
}
I won't get any error from the compiler, but I'd get warning from the linker:
"multiple definition for MyTemp<int>::smDummyVar" ... defined in invalid_group(case1.o) ... rejected in favour of symbol defined in ...(case2.o)
Question: how can I get rid of this warning ?
Thanks a lot in advance for your help !
====================================
inspired by one of the answers in this thread Why can templates only be implemented in the header file?
I found the following solution:
i. remove #include "MyTemp.cpp" in MyTemp.h
ii. specialized.h
#include "MyTemp.h"
typedef MyTemp<int> MySpecialized;
iii. specialized.cpp
#include "MyTemp.cpp"
template class MyTemp<int>;
iv. give specialized.cpp to cmake file
v. include specilized.h in case1.cpp and case2.cpp
the "multiple definition" warning issued by the linker will go away.
Thank you guys for helping !
I have seen many related questions to this problem, but after carefully following advice from members, my problem still persists. The code is quite simple. I only have the following header file ("instrument.h"), which contains the base class and the template class:
#include <stdio.h>
#include <string>
using namespace std;
class Instrument
{
public:
Instrument();
virtual void print() const = 0;
};
template <class parameter> class Equity : public Instrument
{
public:
Equity();
virtual void print() const;
};
Now, in my main function on main.cpp I only do the following:
#include "instrument.h"
#include <iostream>
int main() {
Equity<double> pb;
return 0;
}
Well, I get the very well-known error:
Undefined symbols for architecture x86_64:
"Equity<double>::Equity()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have already changed in Build Settings the C++ standard library to libstdc++, also to default compiler, and so on. Do I have a problem with my project settings? Is perhaps the template wrongly implemented? I was thinking I should also have a instrument.cpp file, but then again definitions for templates must be kept in the header file so that would probably crash too.
Thanks in advance
You declared the default constructors for both Instrument and Equity but defined them nowhere.
Alter their definitions appropriately:
public:
Equity() = default; // Or {} in pre-C++11
// ^^^^^^^^^
(And equivalently for Instrument)
You can also completely omit the declarations of any default constructors for now since you didn't declare any other constructors in both Equity and Instrument and the default constructors will be generated automatically.
This question already has answers here:
Explicit specialization of function templates causes linker error
(2 answers)
Closed 8 years ago.
Having recently discovered templates, I've been trying to get a good grasp on them and came across a usage for them that I'd really like to implement; but having tried multiple things, I keep getting errors.
I'm trying to create a function that can take multiple types of parameters at once in any order.
(I'm using VS 2013.)
What I have right now is an "already defined" error (only when including tem.h in more than one file):
the exact first error (the rest are basically the same just for each test.. overload?):
Error 1 error LNK2005: "void __cdecl test<struct A>(struct A *)" (??$test#UA##$$$V##YAXPAUA###Z) already defined in main.obj c:\Users\User\documents\visual studio 2013\Projects\TemplateTest\TemplateTest\foo.obj TemplateTest
foo is just a .cpp file containing only: #include "tem.h"
tem.h:
#ifndef TEM_H
#define TEM_H
struct A {};
struct B {};
#include <iostream>
template<typename First, typename... Rest>
void test(First *t, Rest&&... args){
test(t);
test(std::forward<Rest>(args)...);
}
template<>
void test<A>(A *val){
std::cout << "Handled A" << std::endl;
}
template<>
void test<B>(B *val){
std::cout << "Handled B" << std::endl;
}
#endif
main.cpp:
#include <iostream>
#include "tem.h"
int main(int argc, char *argv[]){
std::cout << "running test..." << std::endl;
A a;
B b;
test(&a, &b);
return 0;
}
What am I missing that is causing this error?
Edit:
Making each instance of test inline prevents the error, but I don't think that's really the best solution
Function template specializations are not themselves templates, they are normal functions with fancy syntax. Like any other normal function, they should not be defined in header files unless you use the inline keyword.
Either add inline to both specializations, or leave just their declarations in the header and move the definitions to some .cpp file.
The main template definition is OK and should be left in the header intact.
A general advice though is to avoid function template specializations. You can use normal non-template overloads:
void test (A*);
void test (B*);