begin()和data()有什么区别?

3

begin()data()都返回指向第一个元素的迭代器。但是,data()的定义说它返回一个直接指向内部使用的存储所拥有元素的向量的内存数组的指针。我也可以使用它们来访问任何元素。那么它们两者之间有什么不同?请考虑以下示例,

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v;
    v.reserve(5);

    for (int i = 1; i <= 5; i ++) v.push_back(i);
    
    auto it = v.begin();
    auto pos = v.data();

    std::cout << "First element : " << *it << std::endl;
    std::cout << "First element : " << *pos << std::endl;

    std::cout << "Third element : " << it[2] << std::endl;
    std::cout << "Third element : " << pos[2] << std::endl;
}

你错了。只有其中一个方法返回一个迭代器,另一个方法不返回。 - Sam Varshavchik
std::vector<T>::beginstd::vector<T>::data之间的区别。 - Some programmer dude
2
从某种角度来看,OP并没有错。指针是有效的迭代器。迭代器被设计成模拟指针。因此,在这个意义上,begin()data()都返回指向第一个元素的迭代器,只是不同类型的迭代器。 - Remy Lebeau
2个回答

4
std::vector::begin()

v.begin() 返回指向容器中第一个元素的迭代器

std::vector::data()

v.data() 返回指向 vector 内部使用的数组中第一个元素的指针


3

所有容器类型都有一个 iterator,但只有一些容器类型是连续的并支持 data()。例如,

vector<int> v;
copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\n"));
v.data(); // ok

list<int> l;
copy(l.begin(), l.end(), ostream_iterator<int>(cout, "\n"));
l.data(); // no

确实,从int* vector<int>::data()获取的int*符合iterator_traits<int*>::iterator_category == random_access_iterator_tag,并且vector<int>::iterator可以实现为int*。然而,标准没有强制要求这样做,因此使用类似以下方式实现vector<int>::iterator也是合法的:

class vector<T> {
    class iterator {
        vector<T>* v;
        vector<T>::size_type pos;
    };
};

因此,在没有 data() 的情况下,你必须使用诸如 &v[0]&*v.front() 这样的技巧来访问支持 vector 的底层连续内存。这就是在 C++11 引入 data() 之前的状态。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接