Search code examples
c++visual-studiocompiler-errorslinkerlnk2019

I get a linking error (LINK 2019) when I try to augment a class with template


I'm trying to build a simple heap data structure for practice. When I build the version for double it works fine.

class heapt {
public:
    heapt();
    heapt(std::initializer_list<double> lst);
    void print_heapt();
private:
    int size;
    int length;
    double* elem; //points to root
};

Its constructors works perfectly and the heap is printed as it should. But when I try to generalize it with

template< typename Elem>

as:

template<typename Elem>
class heapt {
public:
    heapt();
    heapt(std::initializer_list<Elem> lst);
    void print_heapt();
private:
    int size;
    int length;
    Elem* elem; //points to root
};

for the class definition and as:

template<typename Elem>
heapt<Elem>::heapt(std::initializer_list<Elem> lst) :
size{ static_cast<int>(lst.size()) }, 
elem{new Elem[lst.size()]} 
{
    std::copy(lst.begin(), lst.end(), elem);//Now heaptify elem
    build_heapt(elem, lst.size());
}

for one of the constructors used in the main function.

I get two linking errors:

LNK2019 unresolved external symbol "public: void __thiscall heapt::print_heapt(void)" (?print_heapt@?$heapt@H@@QAEXXZ) referenced in function _main

LNK2019 unresolved external symbol "public: __thiscall heapt::heapt(class std::initializer_list)" (??0?$heapt@H@@QAE@V?$initializer_list@H@std@@@Z) referenced in function _main

The main function is:

{
    heapt<int> hh{ 27,12,3,13,2,4,14,5 };

    std::cout << "Hello" << '\n';

    hh.print_heapt();
}

EDIT: The heapt class is in the "heap.h" file and the definition for the constructor heapt<Elem>::heapt(std::initializer_list<Elem> lst) is in the "heap.cpp" class, which has #include"heap.h" as a header file. The int main function is in a file named "InSo.cpp", which also has #include"heap.h" as a header file.


Solution

  • In your templated class declaration you are using heapt(std::initializer_list<double> lst); but in your definition you are using std::initializer_list<Elem>. You should change the declaration to heapt(std::initializer_list<Elem> lst);

    You are still missing definitions for print_heapt and build_heapt but otherwise it should compile.

    EDIT: In light of you clarifying how your source files are set up, see WhozCraig's comment on your initial post. You can either include the definition of the templated class functions in a heap.hpp file, for example, and include it at the end of your heap.h, or just put them all together in one file, e.g.

    // heap.h
    #ifndef HEAP_H
    #define HEAP_H
    
    #include <initializer_list>
    
    template<typename Elem>
    class heapt {
    public:
        heapt();
        heapt(std::initializer_list<Elem> lst);
        void print_heapt();
    private:
        int size;
        int length;
        Elem* elem; //points to root
    };
    
    #include "heap.hpp"
    
    #endif
    
    //heap.hpp
    #ifndef HEAP_HPP
    #define HEAP_HPP
    
    #include "heap.h"
    #include <algorithm>
    
    template<typename Elem>
    heapt<Elem>::heapt(std::initializer_list<Elem> lst) :
        size{ static_cast<int>(lst.size()) },
        elem{ new Elem[lst.size()] }
    {
        std::copy(lst.begin(), lst.end(), elem);//Now heaptify elem
        //build_heapt(elem, lst.size());
    }
    
    #endif