3

Actually this code works fine in "DEV C++", but when I put it into my "Hacker-Rank" panel it gives this error "reference to function is ambiguous", although all the online compilers are giving errors...

I don't think here function overloading is somewhere interrupting, because this error mostly comes in function overloading.

#include <bits/stdc++.h>
#include <cstdio>
#include<iostream>

using namespace std;


int function(int n);

int main()
{
    int n;
    cin >> n;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');    

    if(n<=0){
        return(0);
    }
    else{
        function(n);
    }

}
int function(int n)
{
    if (n<=9)
    {
        cout<<"experiment";
    }
    
    else{
        cout<<"Greater than 9";
    }
    return 0;
}

The error with clang is:

<source>:20:9: error: reference to 'function' is ambiguous
        function(n);
        ^
<source>:8:5: note: candidate found by name lookup is 'function'
int function(int n);
    ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/bits/std_function.h:111:11: note: candidate found by name lookup is 'std::function'
    class function;
          ^
// ... and more ....
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
Pranshu_Taneja
  • 186
  • 1
  • 1
  • 16
  • Please double and triple check that even for hackerrank participation that antipattern has actually a benefit for you. https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h – Yunnosch Dec 03 '20 at 09:06
  • 1
    Don't `using namespace std;` – molbdnilo Dec 03 '20 at 09:06
  • 1
    If you have already included `` then why include other header ? – Arsenic Dec 03 '20 at 09:10
  • 2
    please do not paraphrase the error message. Include it verbatim in the question. The message has useful information that you should not ignore – 463035818_is_not_an_ai Dec 03 '20 at 09:24
  • I made the title more descriptive. Admittedly it kind of forshadows the two currently existing answers (one of them being mine). I am convinced that the value of this Q/As is improved by this new title. But I will accept if anybody undoes my title change. – Yunnosch Dec 03 '20 at 09:36
  • @Yunnosch imho its a bit too generic and not quite reflecting OPs intent. Should be more like "Why is ... and .. causing trouble in *this code*?", answer can then still explain the general case. I'll try to rephrase it – 463035818_is_not_an_ai Dec 03 '20 at 09:49
  • 1
    @Yunnosch i also added the error message, not sure how this interferes with "although all the online compilers are giving errors..." which is a typo I suppose ("are *not* giving errors" ?!?) – 463035818_is_not_an_ai Dec 03 '20 at 09:54
  • @largest_prime_is_463035818 I think the same. The post would make more sense with that "not". fly_high, please clarify. – Yunnosch Dec 03 '20 at 09:59
  • @Yunnosch not sure if the complete error message is too much of a spoiler and corrupting your answers. Please review and I'd be fine with removing the last part of the message – 463035818_is_not_an_ai Dec 03 '20 at 10:00
  • @largest_prime_is_463035818 I am not afraid. My answer rests on being tested. OPs code gets the error, Vlads Code fixes it. My code fixes it. I also like you title, it is less daring (and blessed by "not me" having edited it...), but it still can provides the value I aimed for. – Yunnosch Dec 03 '20 at 10:03
  • @Yunnosch great. Good luck with finding the duplicates ;) Cheers – 463035818_is_not_an_ai Dec 03 '20 at 10:04
  • Well.... I don't think that anybody using those antipatterns actually reflects to the point to question it. So no question author is likely to accept the dupe. Only if I lose contenance I might succumb to the temptation of actually duping something pointing here. I should not.... But I am human. – Yunnosch Dec 03 '20 at 10:07

3 Answers3

5

For starters this else code block

else{
    function(n);
}

returns nothing.

Though it is allowed but confuses readers of the program because they expect that if there is an explicit return statement in the if sub-statement then a similar return statement should be in the else sub-statement.

It seems the name function declared in the global name space conflicts with the standard name std::function due to the using directive.

using namespace std;

Write

else{
    return ::function(n);
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

The problem is caused by #include <bits/stdc++.h> combined with the directive using namespace std.

<bits/stdc++.h> includes most (all, depending on the age of the version you have with your compiler) headers related to the C++ standard library.

One of the headers included by <bits/stdc++.h> (since C++11) is <functional>, which declares a templated class std::function. std::function has a templated constructor that can accept a single argument of any type.

In your main(), anything declared (visible to the compiler) named function is a candidate for being used by the statement function(n). The directive using namespace std tells the compiler to consider names within std as candidates. According to rules of the language, both your declared function() and std::function are equally good matches for the name function.

The real fix has two parts. The first is to avoid using headers like <bits/stdc++.h> and, instead, only include standard headers that are actually needed by your program.

The second part is to avoid using the directive using namespace std excessively, or even at all. It can cause names (of types, functions, variables, etc) within standard headers to accidentally match names in your code.

If you do a search, you will find plenty of explanations of why to avoid both <bits/stdc++.h> and to avoid using namespace std (or other using directives). Both have their uses, but both introduce hard-to-avoid gotchas (such as you have experienced).

Peter
  • 35,646
  • 4
  • 32
  • 74
1

Vlad has shown that working around the problems caused by using namespace std; can solve your problem. That is a good answer.

Funnily, you can also fix your problem by not applying the antipattern #include <bits/stdc++.h>. Even without Vlads proposed improvement.

#include <limits>
#include <cstdio>
#include<iostream>


using namespace std;

int function(int n);

int main()
{
    int n;
    cin >> n;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');    

    if(n<=0){
        return(0);
    }
    else{
        function(n);
    }

}
int function(int n)
{
    if (n<=9)
    {
        cout<<"experiment";
    }
    
    else{
        cout<<"Greater than 9";
    }
    return 0;
}

More info on why I dare to describe that as "antipattern" is here:
Why should I not #include <bits/stdc++.h>?

Yunnosch
  • 26,130
  • 9
  • 42
  • 54