-1

I have gone through the previous discussions on this topic here, here and here, but found my situation to be unique. Hence this question.

I am trying to create a generic heap class, that depending on a template parameter, can become either a min or a max heap. I am pasting my code below. I am not sure what I am missing, but I either get an "Undefined error" or "expected a type, got st" error.

Heap.h

#ifndef __HEAP__H_
#define __HEAP__H_

#include <iostream>
#include <cstdint>

#define PARENT(x)       x/2
#define LEFTCHILD(x)    2*x
#define RIGHTCHILD(x)   2*x+1

template<typename T, size_t size, typename Comparator>
class Heap
{
private:
    T data[size];
    Comparator comp;
    uint8_t n;

    //Main functions needed for maintaining heap structure
    void BubbleUp(int value);
    void BubbleDown(int value);

    //Helper functions
    void Swap(int value1, int value2);

public:
    bool Insert(int value);
    bool IsEmpty();
    T ExtractTop();
    T PeekTop();
};

#endif

Heap.cpp:

Based on the answer here, I explicitly instantiate the template as shown below:

#include "Heap.h"

template<typename T, size_t size, typename Comparator>
bool Heap<T, size, Comparator>::Insert(int value)
{
    if(n >= size)
        return false;

    data[n] = value;
    BubbleUp(n);
    n++;
    return true;
}

template<typename T, size_t size, typename Comparator>
bool Heap<T, size, Comparator>::IsEmpty()
{
    return (n == 0);
}

template<typename T, size_t size, typename Comparator>
T Heap<T, size, Comparator>::ExtractTop()
{
    T value = data[0];
    data[0] = data[n-1];
    data[n-1] = NULL;
    n--;
    BubbleDown(0);
    return value;
}

template<typename T, size_t size, typename Comparator>
T Heap<T, size, Comparator>::PeekTop()
{
    return data[0];
}

template<typename T, size_t size, typename Comparator>
void Heap<T, size, Comparator>::BubbleUp(int value)
{
    int j = value;
    while(j >= 1)
    {
        if(comp(j, PARENT(j)))
            break;
        else
            Swap(j, PARENT(j));

        j = PARENT(j);
    }
}

template<typename T, size_t size, typename Comparator>
void Heap<T, size, Comparator>::BubbleDown(int value)
{
    int j = value;
    int k = 0;

    while(j < n)
    {
        if(comp(LEFTCHILD(j), RIGHTCHILD(j)))
            k = RIGHTCHILD(j);
        else
            k = LEFTCHILD(j);

        if(comp(j, k))
            Swap(j, k);

        j = k;
    }
}

template<typename T, size_t size, typename Comparator>
void Heap<T, size, Comparator>::Swap(int value1, int value2)
{
    int temp;
    temp = value1;
    value1 = value2;
    value2 = temp;
}

template<typename T>
struct SmallerThan
{
public:
    bool operator()(T instance1, T instance2)
    {
        return(instance1 < instance2);
    }
};

template<typename T>
struct GreaterThan
{
public:
    bool operator()(T value1, T value2)
    {
        return (value1 > value2);
    }
};

SmallerThan<int> st;
GreaterThan<int> gt;
template class Heap<int, 0, st>;
template class Heap<int, 0, gt>;

Main.cpp

template<typename T>
struct GreaterThan
{
public:
    bool operator()(T value1, T value2)
    {
        return (value1 > value2);
    }
};

const size_t size = 8;
Heap<int, size, GreaterThan<int> > maxHeap;

EDIT 1:

Here is the error I get when I compile the above code:

Heap.cpp:118:31: error: type/value mismatch at argument 3 in template parameter list for ‘template<class T, unsigned int size, class Comparator> class Heap’
 template class Heap<int, 0, st>;
                               ^
Heap.cpp:118:31: error:   expected a type, got ‘st’
Heap.cpp:119:31: error: type/value mismatch at argument 3 in template parameter list for ‘template<class T, unsigned int size, class Comparator> class Heap’
 template class Heap<int, 0, gt>;
                               ^
Heap.cpp:119:31: error:   expected a type, got ‘gt’
Community
  • 1
  • 1
Sarvavyapi
  • 810
  • 3
  • 23
  • 35
  • Can you give the full errors? They should even tell you what line is causing them. – Joseph Mansfield Jan 11 '15 at 20:26
  • I have added the error to my question – Sarvavyapi Jan 11 '15 at 20:29
  • I came across the answer referenced above, where the implementation has to be added to the header file. But I want the implementation to remain in the cpp file as mentioned here - http://stackoverflow.com/questions/8752837/undefined-reference-to-template-class-constructor. – Sarvavyapi Jan 11 '15 at 20:32

1 Answers1

1
template class Heap<int, 0, st>;
template class Heap<int, 0, gt>;

As the error says, st and gt are not types. Perhaps you meant:

template class Heap<int, 0, SmallerThan<int>>;
template class Heap<int, 0, GreaterThan<int>>;

However, I still recommend putting your template implementation in the header file, otherwise you're stuck with only these two explicit instantiations.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • Doing the above also throws an error. But I think I have no other alternative other than to have the implementation in the header file. Thanks. – Sarvavyapi Jan 11 '15 at 20:41