我有一组使用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代码有一个hashTable.h的include,后者又包含hashPrototypes.h
在hashPrototypes.h中
int hash(int key);
int hash(const string &key);
我的哈希函数从makefile编译,该makefile根据你输入的内容创建一个可执行文件。例如,我正在使用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;
}
如果您认为错误在makefile中,那么这是makefile代码:
# 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 *
答案 0 :(得分:3)
问题是您已将模板代码放在cpp文件中。 All template code should go in header files。否则,在使用这些模板时会出现链接错误。
答案 1 :(得分:0)
发现问题,它比我想象的要简单,但是约翰关于模板代码帮助的答案。
原来我需要让我的哈希函数(不是myhash)成为一个非模板化的类,并使它成为一个字符串变量。在查看原型后,这对我来说很明显:
int hash(const string &key);
我在初始创建定义时假设它与其他所有内容一样是模板化的类!