由于sort()
中定义的namespace std
必须始终用作std::sort
。但即使没有std
,以下代码也会正确编译。
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> nums = {4,3,1,7,2,0};
sort(nums.begin(),nums.end());
}
但是这段代码没有。
#include <array>
#include <algorithm>
int main()
{
std::array<int,5> nums = {4,1,8,9,6};
sort(nums.begin(),nums.end());
}
在启用gcc 4.8.4
标志的情况下使用-std=c++11
。
从这两段代码片段可以清楚地看出std::vector
与此有关。但我无法弄明白。
答案 0 :(得分:12)
这是argument-dependent lookup。如果使用typeid
来检查所涉及的迭代器的类型:
#include <iostream>
#include <typeinfo>
#include <vector>
#include <array>
int main() {
std::cout << typeid(std::vector<int>::iterator).name() << '\n';
std::cout << typeid(std::array<int, 5>::iterator).name() << std::endl;
return 0;
}
至少在Ideone上,您会得到以下输出:
N9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
Pi
借助Revolver_Ocelot对评论的帮助,我们发现这些类型为__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
和int*
。
对于向量,在通常的名称查找失败后,编译器会在__gnu_cxx
和std
命名空间中搜索sort
函数__gnu_cxx
,因为它是__gnu_cxx::normal_iterator
的命名空间{1}}和std
因为它是其中一个模板参数std::vector<int, std::allocator<int> >
的命名空间。它找到std::sort
。
对于std::array
,迭代器只是int*
,因此依赖于参数的查找不会搜索其他名称空间,也不会找到sort
函数。
答案 1 :(得分:2)
这是参数依赖查找。根据Stroustroup的 C ++编程语言:第4版,这里有两个适用的规则:
1)如果参数是命名空间的成员,则为关联的命名空间 是封闭的命名空间。
2)如果参数是内置类型,则没有关联的命名空间。
在第一种和第二种情况下,begin()和end()返回迭代器。但是,C ++标准将迭代器定义为任何类型的任何变量,可以在其上执行迭代操作。 (换句话说,迭代器是一种通过模板强制执行的设计概念。)
根据另一个答案,第一种情况下的迭代器是与sort()属于同一名称空间的数据类型的变量。但是,第二种情况下的迭代器具有原始数据类型。根据规则#2,这些迭代器没有关联的命名空间。