无法在没有模板参数列表的情况下引用类模板

4
我是一名有用的助手,可以为您翻译文本。
我是C++的新手。这是我的作业,下面是教授给我们的代码,以帮助我们完成这个任务,但它无法编译... 我标记了产生错误的行,并显示了错误消息“Cannot refer to template 'hash' without a template argument list”。
我不确定如何修复它。请问有人能指点我正确的方向吗?
(我已经删除了我认为与错误消息无关的行。)
该类的定义如下:
template <typename HashedObj>
class HashTable
{
public:
    //.... 
private:
    struct HashEntry
    {
        HashedObj element;
        EntryType info;
        HashEntry( const HashedObj & e = HashedObj( ), EntryType i = EMPTY )
           : element( e ), info( i ) { }
    };

    vector<HashEntry> array;
    int currentSize;

    //... some private member functions....

    int myhash( const HashedObj & x ) const
    {
        int hashVal = hash( x ); <<--- line with error

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

        return hashVal;
    }
};

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

--- 在 C++ 文件中的 int hash() 函数 ----
int hash( const string & key )
{
    int hashVal = 0;
    for( int i = 0; i < key.length( ); i++ )
        hashVal = 37 * hashVal + key[ i ];

    return hashVal;
}

int hash( int key )
{
     return key;
}

你正在“滥用命名空间std;”。停止吧。趁你还能停下来的时候就停止吧。如果其他方法都失败了,寻求专业帮助。这不是一种罪行,也不会让你成为坏人,我们都在这里支持你。 - Kerrek SB
1
你可能想把函数声明放在第一次使用它们的地方之上(现在你可能正在引用std::hash,这正是为什么你不应该使用using namespace std;的原因)。而且你没有定义int hash(const string& key);。对于整数来说,Identity是一个可怕的哈希函数。此外,你的哈希函数似乎根本不依赖于表容量,这对我来说有些奇怪。 - Cubic
@KerrekSB 只要在源文件中使用using namespace std;(或任何其他命名空间),而不是在头文件中使用,就没有问题。期望人们总是用std::限定每个库名称是荒谬的。你会对C#中像System.Windows.Controls这样的命名空间说同样的话吗?甚至期望人们不在头文件中这样做也是荒谬的,但这确实会引入问题(这是C++过时模块系统的问题)。 - user1610015
1
@user1610015:实际上,C++语言是否应该更像C#并不重要,如果程序员没有考虑到他们实际编写的语言,那么他们就犯了一个错误。这是他们的错。我并不总是用std限定每个库名称,也不使用using namespace std;,所以你提出了一个错误的二分法。即使你的二分法是真实存在的,即使C++语言对程序员的要求是荒谬的,你仍然必须满足这些要求,否则你的C++代码将是错误的。我更喜欢正确的荒谬代码而不是错误的明智代码。 - Steve Jessop
@SteveJessop 我并没有说C++应该更像C#。我可以通过提到C++/CLI和System::Windows::Controls来表达同样的观点。即使在本机C++中,您也可以在自己的代码或第三方库中使用长命名空间。支持命名空间的所有语言(C++、C#、C++/CLI、VB.NET和Java中的包)几乎都是相同的。至于不用std::限定符或写using namespace std;,我想你是指使用特定项的using(例如using std::string)。这比限定它们更荒谬(如果您只使用该项一次会怎么样?)。 - user1610015
如果我只使用名称一次,通常会在使用它的地方加上std::来限定它,而不是为了没有特定好处而编写额外的代码,就像你想象的那样。如果你决定发明一些你认为我可能会做的荒谬事情,那么当然你会得出你发明的编码风格是荒谬的结论。 - Steve Jessop
1个回答

4
我猜测你正在使用using namespace std;(我能看出你在使用vector而没有使用std ::),并且在std命名空间中存在一个名称为hash的名称,因此存在名称冲突。
你应该使用std :: 而不是引入整个std命名空间,特别是在头文件中,这样一个无辜的用户可以使用#include它,并使他们的程序也受到std的污染。

这就是名字冲突的问题!谢谢你,Seth! :) - selina
2
如果你经常提到名称vector并想要缩写它,你也可以使用using std::vector;。这样可以避免将数百个其他名称带入你从未听说过的范围。 - Steve Jessop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接