0

I'm very new to C++ and I'm trying to reproduce a hash table project from youtube. When I'm creating a new project with a new header filr "hash.h", a main.cpp and a hash.cpp, and when I compile and run the main.cpp I get an error saying that my "hash" was ambigious. My thinking is that my hash collided with the std::hash, that's where the errors are from, but I'm not quite sure how to correct it.. please help! This is done in Code::Blocks :)

main.cpp

#include <iostream>
#include <cstdlib>
#include <string>

#include "hash.h"

using namespace std;

int main(){
    int index;
    hash hashObj;
    index = hashObj.Hash("Amanda");

    cout << index << endl;

    return 0;

}

hash.h

#include <iostream>
#include <cstdlib>
#include <string>


#ifndef HASH_H_INCLUDED
#define HASH_H_INCLUDED

class hash{

public:
    int Hash(std::string key);
};


#endif // HASH_H_INCLUDED

hash.cpp

#include <iostream>
#include <cstdlib>
#include <string>

#include "hash.h"

int hash::Hash(string key){
    int hash = 0;
    int index;

    index = key.length();

    return index;
}
Michael Albers
  • 3,721
  • 3
  • 21
  • 32
Amanda Zhu
  • 55
  • 1
  • 10
  • 4
    The best way to correct it is to get rid of `using namespace std;` everywhere in your code, and [completely forget that this exist in the C++ language](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). – Sam Varshavchik Oct 31 '16 at 01:53
  • 1
    If you just need a hash table use `std::unordered_map` from the C++ standard library. – Cheers and hth. - Alf Oct 31 '16 at 01:54
  • that's an interesting hash function. PHP used that mechanism back in the day to hash function names – Ryan Oct 31 '16 at 01:56

2 Answers2

1

Always prefer not using using namespace std. Or compiler will not be able to determine which hash class you refer to.

This will compile:

#include <iostream>
#include <cstdlib>
#include <string>

#include "hash.h"

int main(){
    int index;
    hash hashObj;
    index = hashObj.Hash("Amanda");

    std::cout << index << std::endl;

    return 0;

}
  • I personally find the cost of all those explicit qualifications, much too high. In contrast, a single qualification is all that's needed when `using namespace std;`. – Cheers and hth. - Alf Oct 31 '16 at 21:00
  • 1
    Yeah, but in the big projects where you have a lot of includes and templates it may cause hard-to-find bugs: – Armen Yeganyan Nov 01 '16 at 09:12
  • 1
    For instance: `int function(T a)` , you may think that it will call the function from the current namespace (but may be in the another file), but actually it will look into T's namespace first. I've fronted with such issue. – Armen Yeganyan Nov 01 '16 at 09:15
  • You can get a name collision for the `function` template, yes, and yes the argument can direct the name lookup for a non-template function. The latter is called ADL, Argument Dependent Lookup, or Koenig lookup after Andrew Koenig who introduced it. But these are separate effects. I don't think I've ever encountered that type of actual function argument has directed the lookup of a function template. Anyway, yes there will be some name collisions, in particular `distance`. They're easy to spot (error) and easy to resolve (qualify, alias, rename). – Cheers and hth. - Alf Nov 01 '16 at 09:47
0

You do indeed have a name conflict with the standard library, as you suspect.


A direct fix:

• In the main program, change the declaration to

::hash hashObj;             //!

• In the hash.cpp file, add a std:: qualification:

int hash::Hash(std::string key){        //!

Instead of the direct fix shown above I'd introduce a namespace for the custom hash table stuff. Then you can write e.g. my::hash. Also, I'd use my usual naming convention of first character uppercase in type names, like Hash, and then the problem isn't there in the first place (but I'd still use a namespace for it).

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • It still says "undefined reference to 'hash::Hash' " on this line: " index = hashObj.Hash("Amanda"); " – Amanda Zhu Oct 31 '16 at 02:23
  • That's because you forgot to compile `hash.cpp` and link with that object file. With most compilers you can do that all simply by adding `hash.cpp` to the command line. – Cheers and hth. - Alf Oct 31 '16 at 02:31
  • In an IDE project (if you're using that), just add both `main.cpp` and `hash.cpp` to the project. For manual invocation of g++, `g++ -std=c++14 -Wall -Wextra main.cpp hash.cpp`. For manual invocation of Visual C++, `cl /nologo /EHsc /GR /W4 main.cpp hash.cpp`. – Cheers and hth. - Alf Oct 31 '16 at 04:19