Why GCC allows calling this function without using its namespace first?(为什么 GCC 允许在不首先使用其命名空间的情况下调用此函数?)
问题描述
<块引用>可能的重复:
什么是参数相关查找"?(又名 ADL,或Koenig Lookup")?
为什么 C++ 参数作用域会影响函数查找命名空间?
今天我遇到了这种奇怪的行为.我可以在不先使用命名空间 Strange
的情况下调用奇怪的Fn,但不允许调用奇怪的Fn2 为什么?
命名空间奇怪{结构体{};无效的奇怪Fn(X&){}无效的奇怪Fn2(int){}}int main(){奇怪::X x;奇怪的Fn(x);//GCC 允许调用这个函数.奇怪的Fn2(0);//错误:未在此范围内声明奇怪的 Fn2.返回0;}
C++ 编译器如何解析符号的作用域?
这叫做 参数依赖查找(或 Koenig 查找)
基本上,如果无法解析符号,编译器将查看参数的命名空间.
第二个函数调用失败,因为strangeFn2
在当前命名空间中不可见,也没有在其参数类型(int
)的命名空间中定义>
您可以看到这如何与运算符函数配合使用:
std::complexc, d;c += d;//没有 ADL 就无法真正工作
或无处不在的 iostream 操作符:
std::string s("hello world");std::cout <<s<
为了好玩,这就是 没有 ADL(没有 using
关键字...)的 hello world 的样子:
std::string s("hello world");std::operator<<(std::cout, s).operator<<(std::endl);//丑陋的!
在存在函数模板的情况下,ADL 和重载解析存在一些隐蔽的极端情况,但我现在将它们排除在答案的范围之外.
Possible Duplicate:
What is "Argument-Dependent Lookup" (aka ADL, or "Koenig Lookup")?
Why does C++ parameter scope affect function lookup within a namespace?
Today I experienced this weird behavior. I can call strangeFn without using namespace Strange
first, but does not allow calling strangeFn2 Why?
namespace Strange
{
struct X
{
};
void strangeFn(X&) {}
void strangeFn2(int) {}
}
int main()
{
Strange::X x;
strangeFn(x); // GCC allows calling this function.
strangeFn2(0); // Error: strangeFn2 is not declared in this scope.
return 0;
}
How does C++ compilers resolve the scope of the symbols?
This is called Argument Dependent Lookup (or Koenig Lookup)
Basically, if a symbol couldn't be resolved, the compiler will look into the namespace(s) of the argument(s).
The second function call fails, because strangeFn2
isn't visible in the current namespace, neither is it defined in the namespace of it's parameter type (int
)
You can see how this works well with operator functions:
std::complex<double> c, d;
c += d; // wouldn't really work without ADL
or the ubiquitous iostream operators:
std::string s("hello world");
std::cout << s << std::endl; // Hello world would not compile without ADL...
For fun, this is what hello world would look like without ADL (and without using
keyword...):
std::string s("hello world");
std::operator<<(std::cout, s).operator<<(std::endl); // ugly!
There are shadowy corner cases with ADL and overload resolution in the presence of function templates, but I'll leave them outside the scope of the answer for now.
这篇关于为什么 GCC 允许在不首先使用其命名空间的情况下调用此函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么 GCC 允许在不首先使用其命名空间的情况下调用此函数?
基础教程推荐
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 从 std::cin 读取密码 2021-01-01