这对我来说似乎有点倒退,但它有效:
#include <iostream>
namespace nTest
{
struct cTest {};
void fTest(cTest& x)
{
std::cout << "nTest::fTest(cTest&) called" << std::endl;
}
}
int main(void)
{
nTest::cTest x;
fTest(x); //Weird! fTest is resolved since its parameter belongs to nTest.
return 0;
}
通常,您需要 nTest::才能访问 fTest,但它属于 nTest 的参数似乎将 nTest 添加到搜索 fTest 的可能范围列表中。参数范围影响函数查找对我来说似乎很奇怪。
这在 GCC 中编译得很好,但我想知道这种用法是否可移植?这种作用域机制的官方定义是什么?
最佳答案
即 ADL(参数相关查找)或 Koenig Lookup(针对功能设计者)。该功能的目的是在许多情况下,同一个命名空间将包含可以应用于这些类型的类型和函数,所有这些都符合 interface .如果 ADL 没有到位,您必须使用 using
将标识符带入范围。声明,否则您必须限定调用。
这变成了一场噩梦,因为该语言允许运算符重载。考虑以下示例:
namespace n {
struct test {};
test operator+( test, test const & ); // implemented
};
int main() {
n::test a,b;
n::test c = a + b; //without ADL: c = n::operator+( a, b )
}
虽然这看起来有点尴尬,但请考虑一下
n
可能是 std
命名空间,test
可能是 ostream
, 和 operator+
可以是 operator<<
:int main( int argc, char** ) {
std::cout << "Hi there, there are " << argc << " arguments" << std::endl;
}
没有 ADL,对
operator<<
的调用必须是明确的,而且您必须知道它们中的哪一个是作为自由函数实现的,而不是作为方法实现的。你知道吗std::cout << "Hi"
正在调用一个免费函数和 std::cout << 5
正在调用成员函数?没有多少人意识到这一点,而且说真的,几乎没有人关心。 ADL 向您隐藏了这一点。
关于c++ - 为什么 C++ 参数范围会影响命名空间内的函数查找?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53571460/