为什么在使用 "using namespace std;" 和 "bits/stdc++.h" 时此代码会出错?

Why do I get an error in this code when using "using namespace std;" and "bits/stdc++.h"?

实际上这段代码在“DEV C++”中运行良好,但是当我将它放入我的“Hacker-Rank”面板时,它给出了这个错误“对函数的引用不明确”,尽管所有的在线编译器都给出了错误。 ..

我不认为这里的函数重载会在某处中断,因为这个错误主要出现在函数重载中。

#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 ....

对于初学者来说,这个 else 代码块

else{
    function(n);
}

return没什么。

虽然它是允许的,但会使程序的读者感到困惑,因为他们期望如果在 if 子语句中有一个明确的 return 语句,那么类似的 return 语句应该在 else 中子语句。

由于 using 指令,全局名称 space 中声明的名称 function 似乎与标准名称 std::function 冲突。

using namespace std;

else{
    return ::function(n);
}

Vlad 已经证明解决由 using namespace std; 引起的问题可以解决您的问题。这是一个很好的答案。

有趣的是,您也可以通过不应用反模式 #include <bits/stdc++.h> 来解决您的问题。即使没有 Vlads 提出的改进。

#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;
}

有关为什么我敢将其描述为“反模式”的更多信息,请参见此处:

问题是由 #include <bits/stdc++.h> 与指令 using namespace std 结合引起的。

<bits/stdc++.h> 包括与 C++ 标准库相关的大部分(全部,取决于您的编译器版本的年龄)headers。

<bits/stdc++.h>(C++11 起)包含的 headers 之一是 <functional>,它声明了一个模板化的 class std::functionstd::function 有一个模板构造函数,可以接受任何类型的单个参数。

在您的 main() 中,任何声明的(对编译器可见的)名为 function 的内容都可能被语句 function(n) 使用。指令 using namespace std 告诉编译器将 std 内的名称视为候选名称。根据语言规则,您声明的 function()std::function 都与名称 function.

同样匹配

真正的修复有两个部分。第一个是避免像 <bits/stdc++.h> 那样使用 headers,而是只包含程序 实际上 需要的标准 headers。

第二部分是避免过度使用指令 using namespace std,甚至根本不使用。它可能导致标准 headers 中的名称(类型、函数、变量等)意外匹配代码中的名称。

如果您进行搜索,您会发现大量关于为什么要避免 <bits/stdc++.h>using namespace std(或其他 using 指令)的解释。两者都有其用途,但都引入了 hard-to-avoid 问题(如您所经历的)。