-1

I'm confused. I wrote a function called hash() and I'm using namespace std for cout,endl and laziness.

Error reference to 'hash' is ambiguous

I know now that a hash function exist in std::

So my question is why the compiler throws this error because I did never include functional.h?

Is there an index anywhere of names from std:: so that I can avoid these names in future when I'm writing my own functions, I can't find anything with google?

I'm confused because of when "everything" is known in std:: why is needed to include the headers? I'm sure that I'm missing something

Maybe my title is not the best but I don't know better.

#include <iostream>
using namespace std;

const int SIZE_TABLE = 10;

int hash(int x)
{
    return x%SIZE_TABLE;
}

int main()
{
    cout<<"hash 24 "<<hash(24)<<endl;
    return 0;
}
Module_art
  • 999
  • 2
  • 9
  • 26
  • 2
    The standard headers may (or may not) include other standard headers. This is one of the reasons to not do `using namespace std;` fyi list of standard headers: http://en.cppreference.com/w/cpp/header – Richard Critten May 09 '18 at 20:50
  • c++ allows for standard headers to include each other. – François Andrieux May 09 '18 at 20:50
  • 2
    1) "_Is there an index anywhere of names from std:: so that I can avoid these names in future when I'm writing my own functions_" That is one reason to avoid [`using namespace std`](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). 2) Headers are allowed to include other headers. What headers, which headers include are up to a specific implementation of a compiler, so you shouldn't count on it. – Algirdas Preidžius May 09 '18 at 20:51
  • 2
    Even if you could find a list of all std identifiers, by using `using namespace std;` you expose yourself to the risk of new identifiers being added in `std` later on. Just don't use `using namespace std;`, this is *specifically* the problem namespaces solve. – François Andrieux May 09 '18 at 20:51
  • Yes, there is an [Index of library names](http://eel.is/c++draft/libraryindex) in the standard. And it is HUGE. – Bo Persson May 09 '18 at 22:04

3 Answers3

3

The compiler try to get the right hash function. Your hash function is implemented under the global namespace, addressed with ::

::hash(1)

In normal cases the compiler would use this namespace, if you call it with

hash(1)

But you say to the compile "hey dude, search every call also in std::" with:

using namespace std;

so he cant decide between

::hash(1)
and
std::hash(1)

using in global scope is a problem in header files, because you import this directive to other files, which include your header file.

In a cpp files, this is matter of taste. I prefer not to use it in cpp, also.

GaRaOne
  • 88
  • 5
2

Step one, don't do this: using namespace std;. You are pulling all the names of the standard library (at least the ones seen by your direct and transitive includes) in and it just so happens that std::hash is a thing - which ends up clashing with your own hash.

If you instead don't pull in all of std but either refer to std stuff explicitly with a std:: prefix or just pull in the stuff you actually want (say std::vector) with something like using std::vector;, then you wouldn't have this problem.

Namespaces exist to sepperate symbols with the same name into seperate domains/boxes. Using using namespace foo; defeats that.

Specifically answering why std::hash is pulled in despite not directly including its header: some other header that you do include includes it or includes some other header which in turn includes it, etc - transitive includes.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
2

why the compiler throws this error because I did never include functional.h?

using namespace std;

Because you have this in the global namespace, you are polluting the global namespace.

It is not well-defined how many symbols you are bringing into the global namespace. A header is allowed to include other headers, as well as define undocumented symbols.

You are also adding your own symbols to the same namespace. Any of your global symbols can collide with a symbol defined in namespace std.

Lesson: Just don't do that and you won't have that problem.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180