c++templatestypedefundefined-symbol

Undefined symbols for typedef and template?


This seems so simple, but I cannot figure out what's wrong. I'm implementing the C++ vector class (only for int, not a template), and functions with iterator templates or typedefs are giving me these errors on compile:

Undefined symbols:
  "void vectorInt::assign<int>(int, int)", referenced from:
      _main in ccNVdR23.o
  "void vectorInt::assign<int*>(int*, int*)", referenced from:
      _main in ccNVdR23.o
      _main in ccNVdR23.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Important parts for the source files are:

vectorInt.h

#include <cstdlib>
#include <stdexcept>

typedef unsigned int size_type;

class vectorInt {
private:
    int* array;
    size_type current_size;
    size_type current_capacity;
public:
    .
    .
    .
    template <class InputIterator>
        void assign(InputIterator first, InputIterator last);
    void assign(size_type n, const int u);
};

#endif // VECTORINT_H

vectorInt.cpp

#include vectorInt.h
.
.
.
template <class InputIterator>
void vectorInt::assign(InputIterator first, InputIterator last) {
    clear();
    InputIterator it = first;
    int count = 0;
    while(it++ != last) {
        count++;
    }

    reserve(count);
    while(first != last) {
        this->push_back(*first++);
    }
}

void vectorInt::assign(size_type n, const int u) {
    clear();
    reserve(n);

    for(int i=0; i<(int)n; i++)
        push_back(u);
}

main.cpp

#include <cstdlib>
#include <stdexcept>
#include <iostream>
#include "vectorInt.h"

using namespace std;

int main(int argc, char** argv) {
    vectorInt first;
    vectorInt second;
    vectorInt third;

    first.assign(7, 100);

    vectorInt::iterator it;
    it = first.begin()+1;
    second.assign(it, first.end()-1); // the 5 central values of first

    int myints[] = {1776,7,4};
    third.assign(myints, myints+3);   // assigning from array.  

    return 0;
}

FYI: I know the main method uses the vectorInt::iterator, but that is not the problem and hence I didn't include it in the source code.


Solution

  • Template code gets two phase compilation. Phase one includes only basic syntax check. The second phase, which is dependent on type T, gets full compilation from the compiler. The class/function will get instantiated based on type T, and the second phase compilation will run against that type.

    Since your code (implementation) is in .cpp file, it would get only first phase compilation, and thus it will not be included in the translation unit - No object file would be generated.

    For templates, you must allow the compiler to compile the entire code. And for the same you need to put entire implementation in header file only. You may also #include respective .cpp file just after the class declaration.