Неопределенная ошибка символа в хеширующей программе C ++

0

У меня есть набор файлов, которые компилируются с помощью makefile, чтобы создать отдельную цепочку хеширования. Программа работает до тех пор, пока я не добавлю код для вставки, удаления и содержит функции. Я вытащил код прямо из книги, но я получаю неоднозначную ошибку, которую я не могу понять, и надеюсь, что кто-то здесь может помочь ее идентифицировать. Я не опубликовал всю программу, потому что я принимаю обоснованное предположение, что причина ошибки не будет найдена вне этого кода (но я мог ошибаться)

Данная ошибка:

Undefined                       first referenced
 symbol                             in file
hash(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)hashApp.o

Кроме того, не уверен, что это актуально, но если я попытаюсь скомпилировать файл.cpp с помощью функций, я получаю:

Undefined                       first referenced
 symbol                             in file
main                                /opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.6/crt1.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status

Вот функции, строки хэшируются в векторе списков:

template <class HashObj>
bool HashTable<HashObj>::contains(HashObj &item)
{
  const list<HashObj> & whichList = theLists[ myhash( item ) ];
  return find( whichList.begin( ), whichList.end( ), item ) != whichList.end( );    
}        

template <class HashObj>
bool HashTable<HashObj>::insert(const HashObj &item)
{
    list<HashObj> & whichList = theLists[ myhash( item ) ];
    if( find( whichList.begin( ), whichList.end( ), item ) != whichList.end( ) )
        return false;
    whichList.push_back( item );
    return true; 
} 

template <class HashObj>
bool HashTable<HashObj>::remove(const HashObj &item)
{
  list<HashObj> & whichList = theLists[ myhash( item ) ];
  typename list<HashObj>::iterator itr = find( whichList.begin( ), whichList.end(), item );

  if( itr == whichList.end( ) )
  return false;

  whichList.erase(itr);
  return true;
 } 

Это функция myhash из того же файла:

 template <class HashObj>
int HashTable<HashObj>::myhash(const HashObj &item) const
{
    int hashVal = hash(item);

    hashVal %= theLists.size();
    if (hashVal < 0)
        hashVal += theLists.size();

    return hashVal;
}

Вышеупомянутый код.cpp имеет include для hashTable.h, который, в свою очередь, включает hashPrototypes.h

В hashPrototypes.h есть

int hash(int key);
int hash(const string &key);

и моя хэш-функция скомпилируется из make файла, который создает исполняемый файл на основе того, что вы вводите. Например, я использую hash1.cpp, поэтому, набрав make HASH = hash1, он должен скомпилировать их все вместе.

Вот мой код hash1.cpp:

#include "hashTable.h"
#include <cmath>
#include <cstdlib>
using namespace std;

template <class HashObj>
int hash(const HashObj &item)
    {
    int hashVal = 0;

    for( int i = 0; i < item.length( ); i++ )
        hashVal = 37 * hashVal + item[ i ];

    return hashVal;
}

Если вы считаете, что ошибка находится в make файле, вот код make файла:

#   Make file for hashing
#   Executable for the program will be in: hashTest

#default function is looked for in hashS1
#to give it another function make=filename without the suffix
HASH = hashS1

$(HASH)Test:  $(HASH).o hashTable.o hashApp.o
    g++ -o $(HASH)Test $(HASH).o hashTable.o hashApp.o

hashApp.o:      hashTable.h hashPrototypes.h hashApp.cpp hashTable.cpp
    g++ -c hashApp.cpp

hashTable.o:    hashTable.h hashTable.cpp $(HASH).cpp
g++ -c hashTable.cpp

$(HASH).o:  hashPrototypes.h $(HASH).cpp
g++ -c $(HASH).cpp

clean:
rm -f *.o 
touch *
Теги:
templates
hash
compiler-errors

2 ответа

3

Проблема в том, что вы поместили код шаблона в файл cpp. Весь код шаблона должен идти в заголовочных файлах. В противном случае вы получаете ошибки ссылок при использовании этих шаблонов.

  • 0
    Был код шаблона в программе, прежде чем я добавил функции вставки, удаления и содержит функции (как, например, вышеупомянутая функция myhash), и он был скомпилирован чисто. Может ли это все еще быть проблемой?
  • 0
    Я не знаю о структуре остальной части вашего кода (это не совсем понятно из вашего вопроса), но у вас есть ошибка ссылки, у вас есть код шаблона в файле cpp, размещение кода шаблона в файле cpp - это хорошо известная причина ошибок ссылки (см. ссылку выше). Вы не должны помещать код шаблона в файл cpp. Исправьте это, и если у вас все еще есть проблемы, спросите снова.
Показать ещё 1 комментарий
0

Нашел вопрос, это было проще, чем я думал, но Джон ответил, что поможет код шаблона.

Оказывается, мне нужно было сделать хэш-функцию (а не myhash) не templated-классом и заставить ее взять строковую переменную. Теперь это очевидно для меня, посмотрев на прототип:

int hash(const string &key);

Я только предположил, что во время моего первоначального создания определения, что это будет шаблонный класс, как и все остальное!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню