-1

I have a program designed with templates to implement a Huffman tree. My HuffmanNode class has two different data types. Here's the class implementation.

#pragma once

template <typename T, typename U> class HuffmanNode 
{
private:
    int frequency;
    T value;
    U code;
    HuffmanNode<T, U>* left, *right;
public:
    HuffmanNode<T, U>() :
        value(' '), frequency(0), left(nullptr), right(nullptr) {}
    HuffmanNode<T, U>(T v, U i) :
        value(v), frequency(i), left(nullptr), right(nullptr) {}
    HuffmanNode<T, U>(HuffmanNode<T, U>* left, HuffmanNode<T, U>* right)
    {
        this->left = left;
        this->right = right;
        frequency = left->getFrequency() + right->getFrequency();
        value = NULL;
    }
};

In my HuffTree class, I have a pointer pointing to a HuffmanNode pointer. I tried declaring the pointer to a HuffmanNode pointer a couple different ways, but either way, I get an error.

I declared it like this:

HuffmanNode<T>** storage;   // Error: 'HuffmanNode': too few template arguments

Then I tried with both data types like this:

template <class T, class U> 
HuffmanNode<T, U>** storage;   // Error: 'HuffTree<T>::storage': only static data member templates are allowed

How would such a pointer be declared?

Edit: I updated the HuffTree class to include both data types in the HuffmanNode pointer, but now I get errors in my HuffmanCode class which includes the HuffTree class. Here's the updated code for the HuffTree class:

#pragma once
#include "HuffmanNode.h"
using namespace std;

template <typename T, typename U> class HuffTree 
{
private:
    HuffmanNode<T, U>** storage;
    int treeSize;
    int capacity;

public:
HuffTree<T, U>(int size)
{
    capacity = size;
    treeSize = 0;
    storage = new HuffmanNode<T, U>*[capacity];
    for (int i = 0; i < capacity; i++)
    {
        storage[i] = NULL;
    }
}
// I get an error in the HuffmanCode class when calling this function
void insert(HuffmanNode<T, U>* rhs)
{
    treeSize++;
    storage[treeSize - 1] = rhs;
    percUp(treeSize - 1);
}
};

Here's the code for the HuffmanCode class which gives me an error now that I fixed the pointer issue:

#pragma once
#include <string>
#include <map>
#include"HuffmanTree.h"
using std::string;
using std::map;
template <typename T, typename U> class HuffmanCode 
{
private:
    string data;
    string encodedData;
    HuffTree<T, U>* tree;
    map<T, U> frequencyTable;
    map<T, U> huffmanTable;
    void buildTree()
    {
        for (map<T, U>::iterator it = frequencyTable.begin();
            it != frequencyTable.end(); ++it)
        {
            /* 
            this line gives me an error: 'HuffmanNode<char,std::string>::
            HuffmanNode(const HuffmanNode<char,std::string> &)': 
            cannot convert argument 1 from 'const std::string' to 'char'
            */
            tree->insert(new HuffmanNode<char, string>(it->first, it->second));
        }
    }
public:
    HuffmanCode<T, U>(T input)
    {
        data = input;
        encodedData = "";
        // create tree to be large enough for worst case
        tree = new HuffTree<T, U>(data.length());
        buildTable();
        buildTree();
    }
    };

Here's my source file to test those functions:

#include <iostream>
#include <string>
#include "HuffmanCode.h"
using namespace std;

int main()
{
    string text;
    cout << "Enter some text:\n";
    getline(cin, text);
    HuffmanCode<string, string>* huffText = new HuffmanCode<string, string>(text);

    huffText->displayTable();
    huffText->displayHuffmanTable();

    string code = huffText->getEncodedString();
    cout << "Encoded string: " << code << endl << endl;
    cout << "Decoded string: " << huffText->decodeString(code) << endl << endl;

    delete huffText;

    return 0;
}

Edited to include relevant code

softengstu
  • 57
  • 1
  • 12
  • 1
    There is no such thing as a "double pointer". And can you write your tree without using templates? If not, don't try to write it using templates. –  Dec 12 '17 at 22:57
  • 1
    Creating templates is hard (at first... Scott Meyers, Herb Sutter, Sean Parent will probably disagree with me). Neil Butterworth's advice is really good. Start by making the classes without them being templates. Once you get them working, then "abstract" out the template from the details. – Eljay Dec 12 '17 at 23:00
  • I edited my post to change "double pointer" to "pointer-to-pointer." I need to write the tree using templates for an assignment. – softengstu Dec 12 '17 at 23:02
  • @Eljay I did that - I had the classes working without being templates and this is the last part I need to "abstract" out. – softengstu Dec 12 '17 at 23:03
  • unless the templates parameters of `HuffmanNode` can be determined from the template parameter of `HuffTree` what you want doesn't make sense. We need more context. – bolov Dec 12 '17 at 23:08
  • Please add a [mcve] directly to your post. Links go dead (or in this case, require me to log into some service). – Miles Budnek Dec 12 '17 at 23:22
  • @MilesBudnek I changed the link to my program on github so you should be able to access that without logging in to anything. – softengstu Dec 12 '17 at 23:59
  • You need to post a [mcve] directly here, not on github. – n. m. could be an AI Dec 13 '17 at 00:23
  • There is no such thing as template class. C++ has *class templates* (note the word order). Class templates are not classes. They are not types. You cannot have a pointer to a template because a template is not a type. Try telling your fellow programmer "we should have a `vector` data member here", and the natural response would be "a `vector` *of what*?" You want to have a pointer to a node... *of what?* – n. m. could be an AI Dec 13 '17 at 00:35

1 Answers1

0

If you can't define the other template argument type then specify it yourself in the HuffTree class. One of these should suit you:

HuffmanNode<T, T> ** storage;

or

HuffmanNode<T, string> ** storage;

(or any other data type you see fit)

Eyal Cinamon
  • 939
  • 5
  • 16
  • I edited my post to include a link to all my code for this program. – softengstu Dec 12 '17 at 23:20
  • The declaration of storage would be the same. I added "complete" class declarations for completeness. You can just copy that line. – Eyal Cinamon Dec 12 '17 at 23:23
  • I tried that but I got many more errors. HuffTree is used in another class which would also need both class T and class U as parameters but that wouldn't work. I posted a link to the full program on github so you can see all my code. – softengstu Dec 12 '17 at 23:58