我很困惑为什么以下代码在某些情况下编译,而不是其他代码。
#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有同样的问题,那为什么会这样呢?
答案 0 :(得分:4)
在最后一种情况下,您表示“CASE 2”,参数是迭代器,标准库实现的类型在命名空间std
中定义。
然后依赖于参数的查找,通常被称为 ADL ,现在不太常见的Koenig查找(在Andrew Koenig之后),在其中找到函数名称命名空间。
ADL是例如在你写
时找到你的非成员operator+
std::string const a = "Blah";
foo( a + "Blah " );
但它也可以找到普通的命名函数,而不仅仅是运算符。
遗憾的是,没有类似的机制可以采用另一种方式,这是一种假设的“功能相关查找”,例如可以找到类中定义的类型,并在参数表达式中用于调用该类的成员函数。
由于允许¹std::vector
使用原始指针作为迭代器,因此无法保证代码可以与其他标准库实现一起使用。
注意:
¹std::vector
和std::basic_string
保证连续的内部缓冲区,这允许原始指针作为迭代器。
功能