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

C++ 将end()迭代器转换为指针,c++,pointers,iterator,C++,Pointers,Iterator,直截了当地说:以下是安全的吗 vector<int> v; int const* last = &*v.end(); // last is never dereferenced 向量v; int const*last=&*v.end(); //最后一个永远不会被取消引用 我担心的是,从迭代器获取普通旧指针的技巧会强制取消对end()迭代器的引用,这是无效的。。。即使只是收回指针 背景:我正在尝试创建一个由任意类型(特别是整数和指向对象的指针)索引的条目集合 模板 ///

直截了当地说:以下是安全的吗

vector<int> v;
int const* last = &*v.end(); 
// last is never dereferenced
向量v; int const*last=&*v.end(); //最后一个永远不会被取消引用 我担心的是,从迭代器获取普通旧指针的技巧会强制取消对end()迭代器的引用,这是无效的。。。即使只是收回指针

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

模板
///需要它实现加法(例如int、随机访问迭代器)
类索引族{
公众:
使用IndexType=IT;
IndexingFamily(IndexType first,IndexType last);
int size()常量;
IndexType运算符[](int i)常量;
私人:
索引类型优先;
索引类型last;
};
模板族::
IndexingFamily(IndexType第一,IndexType最后)
:第一(第一)
,last(last){}
模板自动索引族::
大小()常量->整数{
先返回最后一个;
}
模板自动索引族::
运算符[](int i)常量->索引类型{
先返回+i;
}
模板
结构索引{
使用IndexType=IT;
使用EntryType=ET;
索引类型索引;
入口类型入口;
};
模板
类集合{
公众:
使用IndexType=IT;
使用EntryType=ET;
///有用的方法
私人:
indexingFamily类型indexingFamily;
向量条目;
};
结构MyArbitraryType{};
int main(){
MyArbitraryType obj0、obj1、obj2;
向量v={obj0,obj1,obj2};
使用IndexType=MyArbitrayType常量*;
IndexingFamily IndexingFamily(&*v.begin(),&*v.end());
使用EntryType=double;
使用IndexedEntryType=IndexedEntry;
indexedentry0={&obj0,42.};
indexedentry1={&obj1,43.};
向量项={entry0,entry1};
CollectionOfEntries coll={indexingFamily,entries};
返回0;
}
end()
迭代器的解引用会给出未定义的行为,使用任何标准容器

对于向量,可以使用

pointer_to_end = v.empty() ? 0 : (&(*v.begin()) + v.size());


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

成员函数
end()
返回的迭代器位于向量的最后一个元素之后。你不能取消对它的引用。否则程序将具有未定义的行为

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

vector<int> v;
int const *last = v.data() + v.size(); 
向量v; int const*last=v.data()+v.size(); 如果要使用成员函数end()返回的迭代器,可以编写

vector<int> v;
int const *last = v.data() + std::distance( v.begin(), v.end() ); 
向量v; int const*last=v.data()+std::distance(v.begin(),v.end());
考虑到成员函数data()返回向量数据占用的内存范围的原始指针。

FWIW,“按任意类型索引的条目集合”听起来很像映射的定义…
v.data()+v.size()
会更安全。您知道
end()
指的是最后一个元素之外的元素,对吗?@OliverCharlesworth是的,但在我的真实案例中,地图对数据的处理方式没有帮助processed@JesperJuhl是的,理想情况下,我希望vector::const_iterator==T const*“如果
v
为空,
v.begin()==v.end()
”-为什么你会想要
0
作为结果呢?我理解,但仍然不清楚为什么你想要这个而不是
v.begin()
(&(*v.begin())+v.size())
(相当于
和*v.begin()
)而不是?如果
v.begin()==v.end()
,那么就取消对
v.begin()的引用
有未定义的行为。您的答案是可以的,除了空的情况:指针经过最后一个元素的末尾,在这里选择以统一的方式处理空范围,因此它有点违背了这一点。。。
vector<int> v;
int const *last = v.data() + v.size(); 
vector<int> v;
int const *last = v.data() + std::distance( v.begin(), v.end() );