首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将end()迭代器转换为指针

将end()迭代器转换为指针
EN

Stack Overflow用户
提问于 2016-07-17 12:51:38
回答 2查看 961关注 0票数 4

要说的是:以下内容安全吗?

代码语言:javascript
复制
vector<int> v;
int const* last = &*v.end(); 
// last is never dereferenced

我担心的是,从迭代器中获取一个普通的旧指针的诀窍是强制取消对end()迭代器的引用,这是无效的。即使只是把指针拿回来!

Backgroud:我正在尝试创建一个由任意类型(特别是整数和指向对象的指针)索引的条目集合。

代码语言:javascript
复制
template<class IT>
/// requires IT implements addition (e.g. int, random-access iterator)
class IndexingFamily {
    public:
        using IndexType = IT;

        IndexingFamily(IndexType first, IndexType last);
        int size() const;
        IndexType operator[](int i) const;
    private:
        IndexType first;
        IndexType last;
};

template<class IT> IndexingFamily<IT>::
IndexingFamily(IndexType first, IndexType last) 
    : first(first)
    , last(last) {}

template<class IT> auto IndexingFamily<IT>::
size() const -> int {
    return last-first;
}

template<class IT> auto IndexingFamily<IT>::
operator[](int i) const -> IndexType {
    return first+i;
}

template<class IT, class ET>
struct IndexedEntry {
    using IndexType = IT;
    using EntryType = ET;

    IndexType index;
    EntryType entry;
};

template<class IT, class ET>
class CollectionOfEntries {
    public:
        using IndexType = IT;
        using EntryType = ET;

        /// useful methods
    private:
        IndexingFamilyType indexingFamily;
        vector<EntryType> entries;
};


struct MyArbitraryType {};


int main() {
    MyArbitraryType obj0, obj1, obj2;
    vector<MyArbitraryType> v = {obj0,obj1,obj2};

    using IndexType = MyArbitraryType const*;
    IndexingFamily<IndexType> indexingFamily(&*v.begin(),&*v.end());

    using EntryType = double;
    using IndexedEntryType = IndexedEntry<IndexType,EntryType>;
    IndexedEntry entry0 = {&obj0,42.};
    IndexedEntry entry1 = {&obj1,43.};
    vector<IndexedEntryType> entries = {entry0,entry1};

    CollectionOfEntries coll = {indexingFamily,entries};

    return 0;
}
EN

回答 2

Stack Overflow用户

发布于 2016-07-17 13:03:43

删除end()迭代器会给出任何标准容器的未定义行为。

对于向量,可以使用以下方法获得与end()迭代器对应的指针

代码语言:javascript
复制
pointer_to_end = v.empty() ? 0 : (&(*v.begin()) + v.size());

代码语言:javascript
复制
pointer_to_end = v.data() + v.size();   // v.data() gives null is size is zero

需要检查v.empty(),因为如果v为空,则为v.begin() == v.end()。对于C++11或更高版本,在上面使用nullptr而不是0通常被认为是更好的选择。

票数 2
EN

Stack Overflow用户

发布于 2016-07-17 13:28:33

成员函数end()“点”返回的迭代器在向量的最后一个元素之后。你不能放弃它。否则,程序将有未定义的行为。

您可以通过以下方式获得相应的指针

代码语言:javascript
复制
vector<int> v;
int const *last = v.data() + v.size(); 

如果要使用成员函数end()返回的迭代器,可以编写

代码语言:javascript
复制
vector<int> v;
int const *last = v.data() + std::distance( v.begin(), v.end() ); 

考虑到成员函数data()返回向量数据占用的内存范围的原始指针。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38421411

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档