c++ - 为什么 C++ 参数范围会影响命名空间内的函数查找?

标签 c++ parameters namespaces scope portability

这对我来说似乎有点倒退,但它有效:

#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/

相关文章:

delphi - 为什么const记录参数按值传递?

configuration - 在高级模式下编译时对象被删除或部分折叠 - Google Closure Compiler

c++ - 定义命名空间作用域函数

c++ - 有时发送函数作为参数时出错

c++ - `STRSAFE_NO_TRUNCATION` 和 `STRSAFE_NULL_ON_FAILURE` 值有什么区别?

c++ - munmap_chunk() : invalid pointer in C++ program

java - 带有 JDBC 准备语句的字符串中的圆括号

java - 从REST Web服务中的curl命令获取参数

PHP 命名空间和继承

c++ - int a[] = {1,2,};为什么允许在初始化列表中使用尾随逗号?