c++ - 类模板,允许用户定义类型 C++

标签 c++ templates types defined

我正在做一个关于使用 vector 的开放寻址哈希表的项目。该项目的一个方面是使用模板来允许用户定义 vector 的类型。我已经实现了模板,如果我在编译前创建一个对象,它就可以工作,但是我不知道如何让用户在运行时决定类型。

该程序是面向对象的,必须将类型传递给构造函数。起初我认为简单的 if 语句可以工作,但后来我了解到这是行不通的。谁能帮我解决这个问题?谢谢

#include <iostream>
#include <string>
#include <vector>
using namespace std; 

template <class T>
class OpenHash 
{
private: 
vector <T> hashTab;
vector <int> emptyCheck;
int hashF(string);

public:
OpenHash(int);
int getVectorCap();
int addRecord (T);
int sizeHash();
int find(T);
int printHash();
int deleteEntry(T);

};

template <class T>
OpenHash<T>::OpenHash(int vecSize)
{
 hashTab.clear();
 hashTab.resize(vecSize);
 emptyCheck.resize(vecSize);
        for (int i=0; i < emptyCheck.capacity(); i++)   
        {
        emptyCheck.at(i) = 0;

        }
}

template <class T>
int OpenHash<T>::getVectorCap()
{

 int cap = hashTab.capacity();
 int capE = emptyCheck.capacity();
 cout << cap << capE;
return 0;
}

template <class T>
int OpenHash<T>::hashF (string key)
{
int ascii = 0, hasVal = 0;

    for (int i = 0; i < key.size(); i++)
        {
            ascii += key[i]; 
        }
hasVal = ascii % hashTab.capacity();
return hasVal;
}

template <class T>
int OpenHash<T>::addRecord(T key)
{
if (sizeHash() == emptyCheck.size())
{
    cout << "Your hash table is full cannot add any more records" << endl;
}

else
{
    bool findPos = false;

    for (int j=0; j<hashTab.capacity(); j++)
    {
        if (hashTab.at(j) == key)
        {
            cout << "Element ready exists in hashtable" << endl;
            return 0;
        }

    }
    int hashVal = hashF(key);

        for (int i=hashVal; i<emptyCheck.capacity(); i++)
        {
            if (emptyCheck.at(i) == 0)
            {
                hashTab.at(i) = key;
                emptyCheck.at(i) = 1;
                cout << "Element added at" << '[' << i << ']' <<  endl;
                findPos = true;
                return 0;
            }
            else 
            {
                cout << "Collision probing through..." << endl;
            }
        }

        if (findPos == false)
        {

            for (int x=0; x<emptyCheck.capacity(); x++)
            {
                if (emptyCheck.at(x) == 0)
                {
                    hashTab.at(x) = key;
                    emptyCheck.at(x) = 1;
                    cout << "Element added at" << '[' << x << ']' << endl;
                    findPos=true;
                    return 0; 
                }
            }
        cout <<  "Element could not be added" << endl;

        }


}   
return 1;
}

template <class T>
int OpenHash<T>::sizeHash()
{
int elementsFilled = 0;

    for (int i = 0; i<emptyCheck.capacity(); i++)
        {
            if (emptyCheck.at(i) != 0)
                {
                    elementsFilled++;
                }
        }

return elementsFilled;

}

template <class T>
int OpenHash<T>::find(T key)
{
int hashVal = hashF(key);
bool findLoop = false;


for (int i=hashVal; i < hashTab.capacity(); i++)
{

        if (hashTab.at(i) == key && emptyCheck.at(i) == 1)  
        {
            cout << "Element found at position: " << '[' << i << ']' << endl;
            cout << key << endl;
            findLoop = true;
            return 0;
        }   

        else
        {
            cout << "Element not found at position! Probing through..."  << endl;
            }


    }       

        if (findLoop == false)   
        {


            for (int j = 0; j < hashTab.capacity(); j++)
            {

                if (hashTab.at(j) == key && emptyCheck.at(j) != 0)
                {
                    cout << "Element found at position: " << '['  << j << ']' << endl;
                    cout << key << endl;
                    findLoop = true;
                    return 0;
                }

            }
        cout << "Entry not found" << endl;
        }
return 1;

}

template <class T>
int OpenHash<T>::deleteEntry(T toDel)
{
int hashVal = hashF(toDel);
bool foundDel = false;

    for (int i = hashVal; i<hashTab.capacity(); i++)
    {
        if (hashTab.at(i) == toDel)
        {
            emptyCheck.at(i) = 0;
            foundDel = true;
            cout << "Entry deleted!" << endl;
            return 0;
        }
    }

        if (foundDel == false)
        {
            for (int j=0; j<hashTab.capacity(); j++)
            {   
                if (hashTab.at(j) == toDel)
                {   
                    emptyCheck.at(j) = 0;
                    foundDel = true;
                    cout << "Entry deleted!" << endl;
                    return 0;

                }

            }
        cout << "The member to delete was not found" << endl;
        }   

return 1;
}

template <class T>
int OpenHash<T>::printHash()
{
if (sizeHash() == 0)
{
    cout << "No elements filled to print!" << endl; 
}

    for (int i=0; i<emptyCheck.capacity(); i++)
    {
        if (emptyCheck.at(i) != 0)
            {
                cout << "Record at:" << '[' << i << ']' <<  hashTab.at(i) << endl; 
            }   
    }
return 0;
}

int main () 
{
   cout << "Please input the size of your HashTable" << endl;
   int vecSize = 0;
   cin >> vecSize;
   OpenHash<string> newTable(vecSize);

bool menu = true;
char choice;
while (menu == true)    
{
    cout << "Welcome to the open address hash table program, please input your  choice:" << endl;
    cin >> choice;

        if (choice == 'a')
        {
            cout << "Please type in the record you wish to add:" <<   endl;
            string rec;
            getline(cin, rec);
        newTable.addRecord(rec);
        }
        if (choice == 's')
        {
            cout << "Number of elements filled: " << newTable.sizeHash()  << endl;
        }
        if (choice == 'f')
        {
            cout << "Please enter the string you wish to find" << endl;
            string key;
            getline(cin, key)
            newTable.find(key);
        }
        if (choice == 'p')
        {
            cout << "Printing table..." << endl;
            newTable.printHash();

        }
        if (choice == 'd')
        {
            cout << "Please input the item you wish to delete:" << endl;
            string toDel;
            getline(cin, toDel)
            newTable.deleteEntry(toDel);
        }

        if (choice == 'x')
        {
            cout << "Thankyou" << endl;
            menu = false;
        }
}

return 0;
}

最佳答案

模板是在编译时“决定”的。它们不能在运行时动态决定。

如果你想支持某些类型(例如 intdoublechar 等),你可以在你的代码中显式声明它们程序,它们将被编译,但只有您支持的类型(或您在程序中使用的其他类型)可供用户“选择”:

template<typename T>
class MyTemplateClass { ... };

class template MyTemplateClass<int>;
class template MyTemplateClass<double>;
class template MyTemplateClass<char>;

int main()
{
    // if user wants to create a new int version:
    MyTemplate<int> myInt;
    // etc ...
    return 0;
}

关于c++ - 类模板,允许用户定义类型 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19645360/

相关文章:

c++ - 使用 OpenCV 的边界框

c++ - 优化处理标签(空结构)函数参数

c++ - 成员函数上的 std::is_function?

java - 如何检查 java.lang.reflect.Type 是否为枚举

types - 类型关联常量可以用于将数组大小参数推广到函数吗?

c++ - 将 C 库与 Haskell 库静态链接

c++ - *** 检测到堆栈粉碎 *** : <unknown> terminated Aborted (core dumped) Error only occurring sometimes?

html - 如何防止包含可能弄乱页面样式/模板的 html 标记的动态内容

python - Django:如何在语法错误上向用户获取模板调试信息

Java 十六进制数和条件