vector::begin()和std::begin()之间的差异



在c++中迭代一个向量时,我注意到标准库中有一个begin()函数,还有一个作为vector类成员函数的begin()。如果有的话,两者之间的区别是什么,应该使用哪一个?

示例:

vector<int> numbers;
//Code to put values in my vector
for (vector<int>::iterator i = numbers.begin(); i < numbers.end(); i++)
    cout << *i << 'n';

vs:

vector<int> numbers;
//Code to put values in my vector
for (vector<int>::iterator i = std::begin(numbers); i < std::end(numbers); i++)
    cout << *i << 'n';

std::begin()是在C++11中添加的,以便更容易地编写通用代码(例如在模板中)。最明显的原因是普通C样式数组没有方法,因此没有.begin()。因此,您可以将std::begin()与C样式数组以及具有自己的begin()end()的STL样式容器一起使用。

如果您编写的代码不是模板,则可以忽略std::begin();如果你突然因为它是新的而开始在任何地方使用它,你的程序员同事可能会觉得很奇怪。

向量的std::begin()的实现只调用std::vector<T>::begin(),因此在这种确切的情况下,两者之间没有区别。

std::begin()在通用算法中发挥作用:

template<typename Container>
void my_algorithm(Container c) {
    using std::begin;
    using std::end;
    auto const start = begin(c);  // ADL will find the appropriate overload
    auto const finish = end(c);
    // ... rest of code ...
}

如果编译器优化了代码,那么使用哪一个并不重要。否则,您可能需要使用更OOP的格式:numbers.begin()

此代码已插入用于速度测量的快速工作台:

std::vector<int> arr = {0,1,2};
static void formatA(benchmark::State& state) {
  for (auto _ : state) { // Code inside this loop is measured repeatedly
    std::vector<int>::iterator itrA = arr.begin(); // arr.end();
    benchmark::DoNotOptimize(itrA);
  }
}
// Register the function as a benchmark
BENCHMARK(formatA);
static void formatB(benchmark::State& state) {
  for (auto _ : state) { // Code before the loop is not measured
    std::vector<int>::iterator itrB = begin(arr); // end(arr);
    benchmark::DoNotOptimize(itrB);
  }
}
BENCHMARK(formatB);

所有这些都是使用STL=libstdc++(GNU)编译的,begin()的结果如下:

参数\cpu_time(4dp)1.1094
formatAformatB结论
optim=none
compiler=Clang 11.0
std=c++11
2.19145.1870A比B快2.4倍
optim=none
compiler=Clang 15.0
std=c++20
2.06662.8974A比B快1.4倍
optim=O3
compiler=Clang 11.0
std=c++11
1.0130大致等效的运行时
(等效程序集)
optim=O3
compiler=Clang 15.0
std=c++20
1.00931.0007大致等效的运行时
(等效程序集)

最新更新