0

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.

  • Does this answer your question? [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White May 08 '20 at 11:58
  • I suspect this: [Q: 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?r=SearchResults&s=1|397.2723) will be on the reading list shortly. That is, of course, pure guesswork on my part, since there is no mention whatsoever of what files contain what code in the posted question, but it seems probable, so I'm throwing it out there. – WhozCraig May 08 '20 at 12:03
  • @WhozCraig That worked. I didn't know that using templates would entail shifting all the implementation details into the header file. I copied all the content from "heap.cpp" file into "heap.h" file and it compiles without errors now. Thank you for your help. – CharlieKeith May 08 '20 at 12:23

1 Answers1

0

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
NotAProgrammer
  • 552
  • 1
  • 5
  • 15
  • I'm sorry, I made a typing error when I was writing the question. I'm trying to build with ```heapt(std::initializer_list lst);``` and am getting the same errors mentioned in the question. I've defined print_heapt and build_heapt too, but I didn't mention their definitions since they're not directly related to the errors I'm getting. – CharlieKeith May 08 '20 at 12:18