Вставка объекта в хеш-таблицу... не позволит мне почему-то?

Я разрабатываю простую программу, которая берет объект класса Symbol, который я определил и вставляет в HashTable. Мне был предоставлен файл HashTable.h, полученный из нашего учебника, и, как вы увидите, он предназначен для обработки любого объекта.

Я пытаюсь вставить свой объект через:

hashtable.insert(&temp) //where temp is the object

Однако я получаю следующие ошибки:

Driver.cpp: In function 'int main()':
 Driver.cpp:127:27: error: no matching function for call to 'HashTable<symbol>::insert(Symbol*)'
 Driver.cpp:127:27: note: candidates are:
 In file included from Driver.cpp:12:0:
 SeperateChaining.h:50:10: note: bool HashTable<hashedobj>::insert(HashedObj&) [with HashedObj = Symbol]
 SeperateChaining.h:50:10: note: no known conversion for argument 1 from 'Symbol*' to 'Symbol&'
 SeperateChaining.h:72:10: note: bool HashTable<hashedobj>::insert(HashedObj&&) [with HashedObj = Symbol]
 SeperateChaining.h:72:10: note: no known conversion for argument 1 from 'Symbol*' to 'Symbol&&'
</hashedobj></hashedobj></symbol>

Не могли бы вы, ребята, взглянуть?

EDIT: Когда я пытаюсь вставить по стоимости, как многие из вас предложили, я возвращаю тонну мусора, но разбираюсь в ошибках, есть два:

opt/local/include/gcc47/c++/bits/stl_algo.h:135:7: error: no match for 'operator==' in '__first.std::_List_iterator<_Tp>::operator*<symbol>() == __val'
</symbol>

а также

opt/local/include/gcc47/c++/bits/stl_algo.h:135:7: error: no match for 'operator==' in '__first.std::_List_iterator<_Tp>::operator*<symbol>() == __val' – 
</symbol>

Вот мой файл драйвера и файл hash table.h:

Driver.cpp:

#include <iostream>
 #include <iomanip>
 #include <cassert>
 #include <fstream>
 #include <string>
 #include <vector>
 #include <time.h>
 #include <unistd.h>
 #include <map>
 #include <cstdlib>
 #include <cmath>
 #include "SeperateChaining.h"

 //#include "hash_chn.h"

 using namespace std;

 int TABLE_SIZE; //I know it a global, but it allows the Table Size to be taken in within main() and used in hash()

 size_t hash(const string & key);

 class Symbol
 {
 private:
 int key;
 int type;
 string data;
 public:
 const string & getData() const
 {
 return data;
 }
 int getType() 
 {
 return type;
 }
 int getKey()
 {
 return labs(key);
 }
 void setType(int Type)
 { 
 type = Type;
 }
 void setData(string Data)
 {
 data = Data;
 }
 void setKey(int Key)
 {
 key = Key;
 }
 };

 int main()
 {
 HashTable<symbol> hashtable(TABLE_SIZE);
 Symbol temp;
 vector<symbol> symbols;
 string s;
 int t;
 int hash_key_array[TABLE_SIZE]; //array to hold hash key values

 ifstream file;
 file.open("symbols.txt");

 if(!file)
 {
 cout << "System failed to open file.";
 }
 else
 {
 cout << "File successfully opened" << endl;
 }

 //for loop to read in the string name and the integer that follows the string name from symbols.txt
 while(file >> s)
 {
 temp.setData(s);
 file >> t;
 temp.setType(t);
 symbols.push_back(temp);
 }

 for(int i = 0; i < symbols.size(); i++)
 {
 cout << symbols[i].getData() << "\n";
 cout << symbols[i].getType() << "\n";
 }

 cout << "What would you like the table size to be?" << endl;
 cout << "Note: If the table size is greater than the number of objects" <<
 " in the symbols.txt file, it will inevitably throw a segmentation fault" << endl;
 cin >> TABLE_SIZE;

 for(int j = 0; j < TABLE_SIZE; j++)
 {
 temp.setData(symbols[j].getData());
 cout << temp.getData() << endl;

 temp.setType(symbols[j].getType());
 cout << temp.getType() << endl;

 temp.setKey(::hash(symbols[j].getData()));
 cout << "The key is: " << temp.getKey() << endl;

 cout << endl;

 hash_key_array[j] = temp.getKey();


 for (int i = 0; i < TABLE_SIZE; i++)
 {
 if (i != j)
 {
 if (hash_key_array[i] == hash_key_array[j])
 {
 cout << endl;
 cout << "Collision occurred at " << hash_key_array[i] << endl;
 //rehash();
 //cout << "The new key is: " << temp.getKey() << endl;
 break;
 }
 }
 }

 hashtable.insert(&temp); //problem is here


 }
 }

 size_t hash(const string & key)
 {
 size_t hashVal = 0;

 for(char ch : key)
 {
 hashVal = 37 * hashVal + ch;
 }
 return labs(hashVal);
 }
</symbol></symbol></cmath></cstdlib></map></unistd.h></time.h></vector></string></fstream></cassert></iomanip></iostream>

SeperateChaining.h:

#ifndef SEPARATE_CHAINING_H
#define SEPARATE_CHAINING_H

#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <functional>
//#include "Hash.h"
using namespace std;

// SeparateChaining Hash table class
//
// CONSTRUCTION: an approximate initial size or default of 101
//
// ******************PUBLIC OPERATIONS*********************
// bool insert( x ) --> Insert x
// bool remove( x ) --> Remove x
// bool contains( x ) --> Return true if x is present
// void makeEmpty( ) --> Remove all items

template <typename hashedobj="">
class HashTable
{
 public:

 //Uses the whatever value table_size has
 //Otherwise, it will make a hash table of size 101
 explicit HashTable( int TABLE_SIZE )
 { 
 currentSize = 0;
 theLists.resize(TABLE_SIZE); 
 }

 bool contains( const HashedObj & x ) const
 {
 //represents the correct list in the hash table vector to start looking through
 auto & whichList = theLists[ myhash( x ) ];

 //returns whatever you wanted to search for in the table provided it is there
 return find( begin( whichList ), end( whichList ), x ) != end( whichList );
 }

 void makeEmpty( )
 {
 for( auto & thisList : theLists )
 thisList.clear( );
 }

 bool insert(HashedObj & temp )
 {
 //represents the correct list in the hash table vector to start looking through
 auto & whichList = theLists[myhash( temp )];

 //goes through the beginning and end of the list, and if it
 //doesn't get to the end, then it found the object you wanted to insert in the hash table already
 //prevents duplicate insertions
 if( find( begin( whichList ), end( whichList ), temp ) != end( whichList) )
 return false;

 //otherwise, it has gotten to the end of the list without finding a duplicate
 //and puts what you want to insert in the list
 whichList.push_back( temp );

 // Rehash; see Section 5.5
 if( ++currentSize > theLists.size( ) )
 rehash( );

 return true;
 }

 bool insert( HashedObj && x )
 {
 auto & whichList = theLists[ myhash( x ) ]; 
 if( find( begin( whichList ), end( whichList ), x ) != end( whichList ) )
 return false;
 whichList.push_back( std::move( x ) );

 // Rehash; see Section 5.5
 if( ++currentSize > theLists.size( ) )
 rehash( );

 return true;
 }

 bool remove( const HashedObj & x )
 {
 //represents the correct list in the hash table vector to start looking through
 auto & whichList = theLists[ myhash( x ) ];

 //trying to find x within the list
 //the iterator points to the slot in the list that contains x
 auto itr = find( begin( whichList ), end( whichList ), x );

 //if it gets to the end of the list without finding what you want to remove, then it returns false
 if( itr == end( whichList ) )
 {
 return false;
 }


 //if it finds x, it removes it from the list
 whichList.erase( itr );
 --currentSize;
 return true;
 }

 /*
 void printTable()
 {
 for(int i=0; i < symbols.size(); i++)
 {
 cout << "The hash table contains: " << symbols[i] << endl;
 }
 }
 */

 private: 
 vector<list<hashedobj>> theLists; // The array of Lists
 int currentSize;

 void rehash( )
 {
 vector<list<hashedobj>> oldLists = theLists;

 // Creates new ******-sized, empty table
 theLists.resize( nextPrime( 2 * theLists.size( ) ) );
 for( auto & thisList : theLists )
 thisList.clear( );

 // Copies the old table into the new table
 currentSize = 0;
 for( auto & thisList : oldLists )
 for( auto & x : thisList )
 insert( std::move( x ) );
 }

 size_t myhash( const HashedObj & x ) const
 {
 static hash<hashedobj> hf;
 return hf( x ) % theLists.size( );
 }
 };

#endif
</hashedobj></list<hashedobj></list<hashedobj></typename></functional></algorithm></string></list></vector>
3 ответа

hashtable.insert(& Temp)

Вы должны вставлять по значению, а не по указателю. Удалите оператор &.


Посмотрите на ошибки, которые вы получаете:

SeperateChaining.h:50:10: note: bool HashTable<hashedobj>::insert(HashedObj&) [with HashedObj = Symbol]
SeperateChaining.h:50:10: note: no known conversion for argument 1 from 'Symbol*' to 'Symbol&'
SeperateChaining.h:72:10: note: bool HashTable<hashedobj>::insert(HashedObj&&) [with HashedObj = Symbol]
SeperateChaining.h:72:10: note: no known conversion for argument 1 from 'Symbol*' to 'Symbol&&'
</hashedobj></hashedobj>

Это говорит вам, что вы вызываете insert с Symbol* и insert функции принимает либо Symbol& либо Symbol&&.

Итак, давайте посмотрим на код, который вы называете insert:

hashtable.insert(&temp); //problem is here

Разумеется, вы используете & который является address-of operator который будет принимать адрес temp, который имеет тип Symbol, возвращая ему указатель (что, конечно, относится к типу Symbol*). Таким образом, вы вызываете функцию с Symbol*, чего не ожидают функции.

Sidenote: у вашей реализации есть еще несколько проблем, которые вам нужно будет сортировать. Спросите себя, что temp и что делает HashTable класс делать с l- и ссылки г-значение Symbol, что он принимает?


hashtable.insert(&temp);
 ^

Вы пытаетесь вставить адрес temp. Вот что говорит эта ошибка:

note: bool HashTable :: insert (HashedObj &) [с HashedObj =

Символ] примечание: неизвестное преобразование для аргумента 1 из 'Символ *' в 'Символ и'

Существует версия insert которая принимает ссылку в качестве аргумента. Поэтому вместо указателя вставьте объект по значению:

hashtable.insert(temp);

licensed under cc by-sa 3.0 with attribution.