为什么我能够在没有std :: qualifier的情况下调用这个C ++标准库函数?

时间:2016-04-20 03:20:57

标签: c++ vector stl argument-dependent-lookup

我很困惑为什么以下代码在某些情况下编译,而不是其他代码。

#include <iostream>
#include <vector>
#include <algorithm>

int main(){
  std::vector<int> v(3);
  int a[] = {3, 6, 2};
  std::copy(a, a+3, v.begin());
#define CASE 2
#if CASE == 0
  std::cout << *max_element(a, a+3) << "\n";
#elif CASE == 1
  std::cout << *std::max_element(a, a+3) << "\n";
#else 
  std::cout << *max_element(v.begin(), v.end()) << "\n";
#endif
  return 0;
}

我有三种情况:CASE 0无法编译,因为没有&#34; max_element&#34;。我通过更改为&#34; std :: max_element&#34;来解决这个问题。相反,它 编译并按预期工作。

然而,有趣的是,对于CASE 2(技术上除0或1之外的任何东西),它也可以编译和工作。但是CASE 2和CASE 0有同样的问题,那为什么会这样呢?

1 个答案:

答案 0 :(得分:4)

在最后一种情况下,您表示“CASE 2”,参数是迭代器,标准库实现的类型在命名空间std中定义。

然后依赖于参数的查找,通常被称为 ADL ,现在不太常见的Koenig查找(在Andrew Koenig之后),在其中找到函数名称命名空间。

ADL是例如在你写

时找到你的非成员operator+
std::string const a = "Blah";
foo( a + "Blah " );

但它也可以找到普通的命名函数,而不仅仅是运算符。

遗憾的是,没有类似的机制可以采用另一种方式,这是一种假设的“功能相关查找”,例如可以找到类中定义的类型,并在参数表达式中用于调用该类的成员函数。

由于允许¹std::vector使用原始指针作为迭代器,因此无法保证代码可以与其他标准库实现一起使用。

注意:
¹std::vectorstd::basic_string保证连续的内部缓冲区,这允许原始指针作为迭代器。 功能