xml*_*lmx 6 c++ gcc namespaces compiler-errors language-lawyer
void f() {}
namespace test
{
void f(int) {}
void g() { f(); } // error in gcc 6.2.0
}
int main()
{
test::g();
}
Run Code Online (Sandbox Code Playgroud)
用g ++ -std = c ++ 1z main.cpp编译它,输出如下:
Run Code Online (Sandbox Code Playgroud)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++标准吗?
son*_*yao 12
为什么gcc会隐藏全局命名空间中的重载函数?这符合C++标准吗?
是.简而言之,您不能通过不同的范围重载功能.根据规则不合格的名称查找,为的调用f()
中g()
,这个名字f
可以命名空间内发现test
,那么名称查找停止; 之后发生重载解析(基于找到的名称).这意味着f()
在全局命名空间中根本不会被考虑,即使它看起来更合适.
(强调我的)
对于非限定名称,即名称不在范围解析运算符::右侧的名称,名称查找检查范围如下所述,直到它找到任何类型的至少一个声明,此时查找停止并且不会审查其他范围.
为了编译函数调用,编译器必须首先执行名称查找,对于函数,可能涉及依赖于参数的查找,对于函数模板,可以跟随模板参数推断.如果这些步骤产生多个候选函数,则执行重载解析以选择实际调用的函数.
您可以使用using
将名称引入同一范围,即使它们成为实际的重载函数.
namespace test
{
using ::f; // introduce the name from global namespace
void f(int) {}
void g() { f(); } // fine
}
Run Code Online (Sandbox Code Playgroud)