【问题标题】:Why does gcc hide overloaded functions in the global namespace?为什么 gcc 会在全局命名空间中隐藏重载函数?
【发布时间】:2017-05-13 18:47:10
【问题描述】:
void f() {}

namespace test
{
void f(int) {}    
void g() { f(); } // error in gcc 6.2.0
}

int main()
{
    test::g();
}

g++ -std=c++1z main.cpp编译,输出如下:

main.cpp: In function 'void test::g()':
main.cpp:9:4: error: too few arguments to function 'void test::f(int)'
  f(); // error in gcc
    ^
main.cpp:5:6: note: declared here
 void f(int) {}

我的编译器是 gcc 6.2.0。

为什么 gcc 会在全局命名空间中隐藏重载函数?这符合 C++ 标准吗?

【问题讨论】:

    标签: c++ gcc compiler-errors namespaces language-lawyer


    【解决方案1】:

    为什么 gcc 会在全局命名空间中隐藏重载函数?这符合 C++ 标准吗?

    是的。简而言之,您不能通过不同的范围重载函数。根据unqualified name lookup的规则,对于g()中的f()的调用,在test命名空间中可以找到名称f,则停止名称查找; overload resolution 之后发生(基于找到的名称)。这意味着全局命名空间中的f() 根本不会被考虑,即使它在这里看起来更合适。

    (强调我的)

    对于非限定名称,即不会出现在 范围解析运算符 :: 的右侧,名称查找检查 范围如下所述,直到找到至少一个声明 任何类型的,此时查找停止并且没有进一步的范围 检查。

    为了编译一个函数调用,编译器必须首先执行 名称查找,对于函数,可能涉及参数相关 查找,并且对于函数模板,可以在模板之后 论证推论。 如果这些步骤产生了多个候选人 函数,然后执行重载决议以选择函数 这实际上会被调用。

    您可以使用using 将名称引入同一作用域,即使它们成为实际的重载函数。

    namespace test
    {
        using ::f;        // introduce the name from global namespace
        void f(int) {}    
        void g() { f(); } // fine
    }
    

    【讨论】:

    猜你喜欢
    • 2015-02-17
    • 1970-01-01
    • 2016-07-21
    • 2021-11-10
    • 2013-11-19
    • 2012-11-07
    • 2012-02-10
    • 2019-11-15
    • 1970-01-01
    相关资源
    最近更新 更多