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 允许在不首先使用其命名空间的情况下调用此函数?
基础教程推荐
- 初始化列表*参数*评估顺序 2021-01-01
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- CString 到 char* 2021-01-01
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
