【问题标题】:Why do I get an error in this code when using "using namespace std;" and "bits/stdc++.h"?为什么我在使用“使用命名空间 std;”时会在此代码中出现错误和“位/stdc++.h”?
【发布时间】:2021-03-15 06:43:06
【问题描述】:

实际上,这段代码在“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 ....

【问题讨论】:

  • 请仔细检查一下,即使对于hackerrank 参与,反模式实际上对您有好处。 stackoverflow.com/questions/31816095/…
  • 不要using namespace std;
  • 如果你已经包含了&lt;bits/stdc++.h&gt;那为什么还要包含其他标题?
  • 请不要解释错误信息。将其逐字包含在问题中。该消息包含您不应忽略的有用信息
  • @Yunnosch 我还添加了错误消息,不确定这如何干扰“尽管所有在线编译器都给出错误......”我想这是一个错字(“是 not 给出错误" ?!?)

标签: c++ function namespaces ambiguous name-lookup


【解决方案1】:

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

else{
    function(n);
}

什么都不返回。

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

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

using namespace std;

else{
    return ::function(n);
}

【讨论】:

  • 反模式制造麻烦的好例子。我很想对这里提到的许多问题进行欺骗-近距离投票....
  • 你用几行解释了真棒我在许多代码中都有这个错误但现在我只是更改了函数的名称......是的,它适用于各种情况......谢谢...
  • @fly_high 无论如何最好使用限定名。
【解决方案2】:

问题是由#include &lt;bits/stdc++.h&gt; 结合指令using namespace std 引起的。

&lt;bits/stdc++.h&gt; 包含与 C++ 标准库相关的大多数(全部,取决于您的编译器版本的年龄)头文件。

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

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

真正的修复有两个部分。首先是避免使用像&lt;bits/stdc++.h&gt; 这样的标头,而是只包含您的程序实际上需要的标准标头。

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

如果您进行搜索,您会发现很多解释为什么要同时避免 &lt;bits/stdc++.h&gt; 和避免 using namespace std(或其他 using 指令)。两者都有其用途,但都引入了难以避免的陷阱(例如您所经历的)。

【讨论】:

    【解决方案3】:

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

    有趣的是,您也可以通过不应用反模式#include &lt;bits/stdc++.h&gt; 来解决您的问题。即使没有 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;
    }
    

    更多关于我为什么敢将其描述为“反模式”的信息在这里:
    Why should I not #include <bits/stdc++.h>?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      • 1970-01-01
      • 2019-06-21
      • 2023-01-29
      • 2021-04-10
      • 2021-08-10
      • 1970-01-01
      相关资源
      最近更新 更多