繁体   English   中英

将向量迭代器转换为指针

[英]Convert vector iterator to pointer

有没有办法将vector::iterator转换为指针而无法访问向量本身? 这仅在vector可用时才有效:

typedef vector<int> V;
int* to_pointer1( V& v, V::iterator t )
{
    return v.data() + (t-v.begin() );
}

但是,如果没有vector ,怎么能这样做呢? 这不起作用:

int* to_pointer2( V::iterator t )
{
    // the obvious approach doesn't work for the end iterator
    return &*t;
}

事实上,我本来希望这是一个非常基本和流行的问题,但由于某种原因,我找不到它。

一般来说,你不能保证对应于指的是普通的载体项目迭代器的指针。

特别是std::vector<bool>是专用的,因此&*it甚至不会编译。

然而,对于其他向量,它只有1个正式迂腐,阻止你做&*it也为最终迭代器。 在C99中,正如我记得的那样,当p是结束指针时,正式有效做&*p ,并且std::vector的目标是支持所有普通的原始数组符号。 如果我需要这个,我会忽略正式迂腐,并编写代码,以期对标准的未来修订将消除那个想象的障碍。

所以,在实践中,只需做&*it :)

#include <iostream>
#include <vector>
using namespace std;

auto main() -> int
{
    vector<int> x( 5 );
    cout << &*x.begin() << " " << &*x.end() << endl;
    cout << &*x.end() - &*x.begin() << endl;        // Works nicely IN PRACTICE.
}

但请记住,你不能为vector<bool>做这个。


1)在评论别处用户十五边形的言论:“尝试-D_GLIBCXX_DEBUG ,如下记载: gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode_using.html 。” G ++经常提供携带任何正式的UB到前面的一些手段,例如正式UB循环的“优化”。 在这种特殊情况下的解决方案只是不要求它这样做,但更一般地,人们可能必须明确地要求它不这样做。

不,这目前不可行。 n3884 连续迭代器:随机访问的改进迭代器提出了一个自由函数std::pointer_from ,它可以满足你的要求:

表达式: std::pointer_from(a)
返回类型: reference
操作语义:如果a是可解除引用的,则std::address_of(*a) ; 否则,如果a可从可解除引用的迭代器b到达,则std::pointer_from(b) + (a – b) ; 否则是有效的指针值([basic.compound])。

对于最终迭代器,你所要求的是不可能的; 根据定义,结束迭代器指向超出数组末尾的假设元素(即取消引用它,总是UB)。

你说:

@Nick我想让它适用于任何有效的迭代器,包括结尾。 它应该是可能的,因为to_pointer1也涵盖了这种情况。

to_pointer1 包括这种情况。 to_pointer1返回一个无效的内存地址(实际上该地址可能有效,但那里没有数据)。

我用这个模板:

template<typename It>
inline auto ptr(It const&it) -> decltype(std::addressof(*it))
{ return std::addressof(*it); }

实际上,这适用于大多数迭代器。 例外的是其中任一对象*it没有被定义( vector<bool>::iterator ),或者it 指向无处(而不是一个过去最最后一个元素)。 为了你的特殊目的,它应该没问题,除了vector<bool> (当指针的概念不合理时)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM