redefinition of template<class T> in C++
Asked Answered
P

5

7

I have searched and searched for a solution to my problem but I cannot seem to find one. I am using Code::Blocks and I am getting a redefinition error of a template class.

Here is my "vectorAux.h" file:

#ifndef vectoraux_h
#define vectoraux_h

#include <vector>
#include <algorithm>
#include <iostream>

template <typename T>
void removeDup(std::vector<T> & v);

template <typename T>
unsigned seqVectSearch(const std::vector<T> & v, unsigned first,
               unsigned last, const T& target);

template <typename T>
void writeVector(const std::vector<T> & v);

#include "vectorAux.cpp"
#endif

and here is my "vectorAux.cpp" file:

#include "vectorAux.h"

#include <vector>
#include <algorithm>
#include <iostream>

template <typename T>
void removeDup(std::vector<T> & v)
{
    std::vector<int> vector1;
    unsigned i, last = v.size();

    for(int j = 0; j <= v.size(); j++)
    {
        std::cout << seqVectSearch(v, j, last, j);
        if(seqVectSearch(v, j, last, j) != v[i])
            vector1.push_back(seqVectSearch(v, j, last, j));
    }
}

template <typename T>
unsigned seqVectSearch(const std::vector<T> & v, unsigned first,
                       unsigned last, const T& target)
{
    unsigned i = first;
    while((v[i] != target) && (v[i] <= last))
    {
        if(v[i] == target)
            return i;
        i++;
    }
    return last;
}

template <typename T>
void writeVector(const std::vector<T> & v)
{
    unsigned i;
    unsigned n = v.size();

    for (i = 0; i < n; i++)
        std::cout << v[i] << ' ';
    std::cout << std::endl;
}

the final file for this program is "vectorDriver.cpp" but this one has no errors. This one just runs the program by calling the functions:

#include "vectorAux.h"
#include <vector>
#include <iostream>

void fillVector(std::vector<int> & vect);

int main()
{
  using namespace std;

  vector<int> vect;

  fillVector(vect);
  cout << "Testing removeDup" << endl;
  cout << "Original vector is  ";
  writeVector(vect);

  removeDup(vect);
  cout << "Vector with duplicates removed is  ";
  writeVector(vect);
  cout << endl;
  writeVector(vect);

  return 0;
}

void fillVector(std::vector<int> & vect)
{
  int arr[] = {1,7,2,7,9,1,2,8,9};
  unsigned arrsize = sizeof(arr)/sizeof(int);

  vect = std::vector<int>(arr, arr+arrsize);
}

I would really appreciate any and all help/advice that is given! I have looked around for a while and each source that I have found has said to guard the header file, but I have already done that and my problem still ensues.

Prostyle answered 23/10, 2012 at 7:11 Comment(2)
Code::Blocks is not a compiler but an IDE. It just displays the errors the compiler outputs.Mouthpart
As a side note: seqVectSearch == std::find and writeVector == std::copy(..., std::ostream_iterator<T>).Alenaalene
I
7

You include vectorAux.cpp in vectorAux.h. I would guess that you are also compiling vectorAux.cpp separately. So you end up compiling the code in vectorAux.cpp twice.

Answer is simple, move the code from vectorAux.cpp to vectorAux.h, delete vectorAux.cpp, you don't need it.

Template code almost always goes in header files.

Ilan answered 23/10, 2012 at 7:16 Comment(1)
I agree with the first paragraph. However, it's totally fine to separate the declaration of template and the definition of template as long as you explicitly instantiate the template. Check here for the detail #116203Gavage
P
3

The contents of your "VectorAux.cpp" should be inside the "VectorAux.h" because you define a template class.

Parts answered 23/10, 2012 at 7:16 Comment(1)
I don't particular recommend it, but it is actually quite a common technique, to split template declaration and defintion into two separate files and then include the implementation file into the headerfile as the OP did. The mistake was to also include the headerfile in the cpp file and/or to directly compile the cpp file.Lull
M
2

The simple answer is: Templates should not be split into source and header files. Keep it all in the header file when using templates.

Mouthpart answered 23/10, 2012 at 7:15 Comment(1)
I don't particular recommend it, but it is actually quite a common technique, to split template declaration and defintion into two separate files and then include the implementation file into the headerfile as the OP did. The mistake was to also include the headerfile in the cpp file and/or to directly compile the cpp file.Lull
M
1

Remove your .cpp of your templated class from your project source files. You are currently compiling the .cpp file twice; once because it is in your project and secondly because your .h is including it. Also, remove the .h inclusion from your .cpp, you don't need it since the header is including the .cpp at the bottom. This is one of the unfortunate problems of separating out templated classes.

Mckinnon answered 15/5, 2016 at 5:31 Comment(2)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewSick
This will fix the problem. If you have the .cpp with the definitions of a templated class in the project when you compile, you get this error.Mckinnon
L
0

The error happens during the compilation of the vectorAux.cpp file, because you are including the header file, which in turn includes the implementation file. This way, you end up with the content of the cpp file being duplicated.

If you really do want to split the implementation and declaration of the template functions into two separate files, there are two things you should do:

  1. Don't include the headerfile in the implementation file.
  2. Don't add the cpp file to the files being translated by the compiler.

Any one of those two options will get rid of your compiler error, but you really should do both.

Lull answered 15/5, 2016 at 20:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.