0

The following is a Template classes tutorial from learncpp.com :

main.cpp

#include "Array.h"

int main()
{
    Array<int> intArray(12);
    Array<double> doubleArray(12);

    for (int count = 0; count < intArray.getLength(); ++count)
    {
        intArray[count] = count;
        doubleArray[count] = count + 0.5;
    }

    for (int count = intArray.getLength()-1; count >= 0; --count)
        std::cout << intArray[count] << "\t" << doubleArray[count] << '\n';

    return 0;
}

Array.h

#ifndef ARRAY_H
#define ARRAY_H

#include <assert.h> // for assert()

template <class T>
class Array
{
private:
    int m_length;
    T *m_data;

public:
    Array()
    {
        m_length = 0;
        m_data = nullptr;
    }

    Array(int length)
    {
        m_data = new T[length];
        m_length = length;
    }

    ~Array()
    {
        delete[] m_data;
    }

    void Erase()
    {
        delete[] m_data;
        // We need to make sure we set m_data to 0 here, otherwise it will
        // be left pointing at deallocated memory!
        m_data = nullptr;
        m_length = 0;
    }


    T& operator[](int index)
    {
        assert(index >= 0 && index < m_length);
        return m_data[index];
    }

    // The length of the array is always an integer
    // It does not depend on the data type of the array
    int getLength();
};

#endif

Array.cpp

#include "Array.h"

template <typename T>
int Array<T>::getLength() { return m_length; }

Error : unresolved external symbol "public: int __thiscall Array::getLength(void)" (?GetLength@?$Array@H@@QAEHXZ)

Explanation : In order for the compiler to use a template, it must see both the template definition (not just a declaration) and the template type used to instantiate the template. Also remember that C++ compiles files individually. When the Array.h header is #included in main, the template class definition is copied into main.cpp. When the compiler sees that we need two template instances, Array, and Array, it will instantiate these, and compile them as part of main.cpp. However, when it gets around to compiling Array.cpp separately, it will have forgotten that we need an Array and Array, so that template function is never instantiated. Thus, we get a linker error, because the compiler can’t find a definition for Array::getLength() or Array::getLength().

What does the explanation mean? i am having a hard time understanding the explanation provided by Alex(learncpp's creator).

kira55
  • 87
  • 4
  • Does this answer your question? [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Lukas-T Dec 29 '19 at 21:26

1 Answers1

0
// The length of the array is always an integer
// It does not depend on the data type of the array
int getLength();

It's true that the length of the array does not depend on the data type. However, Array<double>::getLength() and Array<int>::getLength() are two different functions. You can implement getLength() for all template instantiations only if it is implented inline. For that reason, it's not possible to implement it in a .cpp file.

R Sahu
  • 204,454
  • 14
  • 159
  • 270