4

I'm new to C++. This is for my homework and below is the code that was given to us by the professor to help us work on this assignment but it doesn't compile... I've marked the line where error is generated and the error message is "Cannot refer to template 'hash' without a template argument list".
I'm not sure how to fix it. Can someone point me to the right direction, please?
(I've removed the lines that, I assume, is irrelevant to the error message.)

The class is defined as:

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 );

--- and int hash() function in cpp file ----

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;
}
selina
  • 71
  • 1
  • 2
  • 5
  • You're `abusing namespace std;`. Stop it. Stop it now, while you still can. Seek professional help if all else fails. It's not a crime, it doesn't make you a bad person, and we're all here to support you. – Kerrek SB Oct 21 '12 at 00:41
  • 1
    You might wanna put your function declarations above the place where you first use them (right now you're probably referring to std::hash, which is exactly the reason why you shouldn't use `using namespace std;`). And you don't have a definition for `int hash(const string& key);`. Identity is a terrible hash function for integers. Also, your hash function doesn't seem to depend on your table capacity at all, which seems somewhat strange to me. – Cubic Oct 21 '12 at 00:42
  • @KerrekSB There's nothing wrong with `using namespace std;` (or any other namespace) as long as you do it in a source file and not in a header file. It's ridiculous to expect people to always qualify every library name with std::. Would you say the same for C# with namespaces like System.Windows.Controls? It's even ridiculous to expect people not to do it in header files, but that does introduce problems (and it's the fault of C++'s outdated module system). – user1610015 Oct 21 '12 at 00:50
  • 1
    @user1610015: it really doesn't matter whether the C++ language "should" be more like C#, if programmers don't account for the language they're actually writing in, then they've made a mistake. It's their fault. I don't always qualify every library name with `std` and neither do I use `using namespace std;`, so you present a false dichotomy. Even if your dichotomy were real, and even if the demands made of programmers by the C++ language are ridiculous, you *still* have to satisfy those demands or else your C++ code will be wrong. I prefer correct ridiculous code to incorrect sensible code. – Steve Jessop Oct 21 '12 at 01:22
  • @SteveJessop I didn't say that C++ should be more like C#. I could have made the same point mentioning C++/CLI and System::Windows::Controls. Even in native C++ you can have long namespaces in your own code or in third-party libraries. Namespaces are pretty much the same in all languages that support them (C++, C#, C++/CLI, VB.NET, and packages in Java). As for not qualifying with std:: nor writing `using namespace std;`, I guess you mean using `using` with specific items (`using std::string`). That's even more ridiculous than qualifying them (what if you only use the item once?). – user1610015 Oct 21 '12 at 03:59
  • @user1610015: If I only use the name once I generally qualify it with `std::` in the one place I use it, rather than write extra code for no particular benefit as you seem to imagine. If you're determined to invent ridiculous things that you think I might do, then of course you'll conclude that your invented coding style is ridiculous. – Steve Jessop Oct 21 '12 at 12:32

1 Answers1

4

I suspect you are using namespace std; (I can tell because you are using vector without std::) and there exists a name hash in the std namespace, so the names conflict.

You should use std:: instead of bringing in the entire std namespace, especially in an header file where an innocent user can #include it and pollute their program with std too.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • It *was* the name conflict! Thank you, Seth! :) – selina Oct 21 '12 at 00:45
  • 2
    You can also do `using std::vector;` if you mention the name `vector` a lot and want to abbreviate it. This avoids dragging hundreds of other names into scope that you've never heard of. – Steve Jessop Oct 21 '12 at 01:28