C++ Variadic Template "multiple definitions"/"already defined" Issue [duplicate] - c++

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*);

Related

Wrong symbols linked. Why? [duplicate]

This question already has answers here:
C++ Multiple Definition of Struct
(2 answers)
Why is there no multiple definition error when you define a class in a header file?
(3 answers)
Closed 1 year ago.
C++ translator seems uses correct declared structs of the same name, but then linker mismatches them without any warning or error! And this also leads to UB, because at least inappropriate ctor/dtor are used for the memory region.
Here is minimal sandbox code. Each struct Test should be treated as some internal non-public structure used only in one own .cpp file.
file1.cpp
#include <iostream>
using namespace std;
void someFunc();
struct Test
{
Test() { std::cout << "1 "; }
~Test() { std::cout << "~1" << std::endl; }
};
int main()
{
{
Test test;
}
someFunc();
return 0;
}
file2.cpp
#include <iostream>
struct Test {
Test() { std::cout << "2 "; }
~Test() { std::cout << "~2" << std::endl; }
};
void someFunc() {
Test test;
}
(Downloadable and buildable CMake-project just in case: https://file.io/dzafv409B2t0)
Output will be:
1 ~1
1 ~1
So, I expected:
Successful build with output: 1 ~1 2 ~2
Or failed build with multiple definition error
Yes, I can resolve the problem if:
Rename the struct
Put the struct into anonymous namespace - force internal linkage
...but this doesn't answer the main question:
Why linker behaves so? Why does it silently links to first available matching symbol (among several) instead of reporting multiple definition error?
Update: As I understood, this mechanism allows to include header with class declaration (with inline code) into several different source files without multiple definition problem.

Linking error with methods using class templates

I need to use my class template inside one of the member functions (class methods), as shown below :
Declaration :
template <int N>
class Array
{
private :
int var[N];
public :
void increment ();
};
Definition :
template <int N>
void Array<N> :: increment ()
{
for (int i = 0; i < N; i++)
{
cout << i << endl;
}
}
Instantiation and method call in Main.cpp:
Array <5>var;
int main()
{
var.increment();
system ("pause");
}
I keep getting a linking error saying "1 unresolved externals" in Main.obj (Main.cpp).
Please consider all "cout" and "using namespace std" to be already done in the background. I'm just adding the relevant code here.
My main problem is that I don't know how to use the class template parameter (N) inside one of the class's methods.
UPDATE: Sorry I'm late but I've found a solution to this. Thanks for the help all.
Just to close this thread because I forgot about it long ago. The problem seems to be the fact that templates can only be implemented in a header file of .tpp file. The link given by #user4581301 helped in clearing this up.
This is the link

C++ Template errors? [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 6 years ago.
I'm trying to learn how to use templated classes. I've created a simple templated class numbers that holds 2 numbers that can be any data type. Then I made a method that returns the bigger number of the two in the object. For some reason I keep getting linker errors though... Here's the errors and code. Not sure what's wrong, Visual Studio didn't underline anything in my code.
They say "unresolved external symbol" if it's too small to read.
templated.h
template <class T>
class numbers {
public:
numbers(T x, T y);
T bigger();
private:
T a, b;
};
templated.cpp
#include "templated.h"
#include <iostream>
using namespace std;
template <class T>
numbers<T>::numbers(T x, T y) {
a = x;
b = y;
}
template <class T>
T numbers<T>::bigger() {
return a > b ? a : b;
}
main.cpp
#include <iostream>
#include "templated.h"
using namespace std;
int main() {
numbers <int>pair(1, 2);
cout << pair.bigger() << endl;
return 0;
}
Thanks for reading!
You're not supposed to put template implementations in a cpp/c file. Move them all to your .h file.
This is because cpp files are supposed to take functions that compile into implementation libraries (like dll files or compiled objects), while template functions have undefined types (yet), whose types get defined at compile time.
You can, however, put specializations of your template functions in the cpp file, where you specify what types you want to include in your compiled objects.

Call Base Default constructor Template Class [duplicate]

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

How to compile Templates located in different files in C++?

When I put all the source in one file, the program successfully builds. However when I split them into header files, I get a link error.
The main of my program:
//C++_Class_Templates.cpp
#include <iostream>
#include <vector>
#include "Queue.h"
using namespace std;
//Usage for C++ class templates
void main()
{
MyQueue<int> q;
q.Add(1);
q.Add(2);
}
The Queue.h looks like this
#pragma once
#include <vector>
template <typename T>
class MyQueue
{
std::vector<T> data;
public:
void Add(T const &);
void Remove();
void Print();
};
and the Queue.cpp looks like this:
#include "Queue.h"
template <typename T> void MyQueue<T> ::Add(T const &d)
{
data.push_back(d);
}
When I try to build it, I get this error:
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall
MyQueue<int>::Add(int const &)" (?Add#?$MyQueue#H##QAEXABH#Z) referenced in function _main
The short answer is: "you don't."
The longer answer is: well, it's basically the same as the short answer. For more information, see the C++ FAQ Lite entry "Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?" Except for certain limited-use scenarios (like when you have a small set of known arguments with which you will use the template and you can explicitly instantiate it with those types), the definition of the template must be available when you try to use it.
Separating declaration and definition for templates is not trivial.
The compiler must see the definition to be able to compile a specialization but it must also know the parameters to use. C++ was designed to be compiled one "compile unit" at a time and those two parts (the definition and the parameters) must be visible at the same time.
So either you put all a list of all specializations you will need in the implementation file of the template or you put the whole definition in the .h file. Both of those two solutions have however drawbacks.
See this answer to the same problem you are facing for a more complete explanation.