C++ 将迭代器转换为指针?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/743055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert iterator to pointer?
提问by Frank
I have a std::vector
with n
elements. Now I need to pass a pointer to a vector that has the last n-1
elements to a function.
我有一个std::vector
与n
元素。现在我需要将一个指向具有最后一个n-1
元素的向量的指针传递给函数。
For example, my vector<int> foo
contains (5,2,6,87,251)
. A function takes vector<int>*
and I want to pass it a pointer to (2,6,87,251)
.
例如,我的vector<int> foo
包含(5,2,6,87,251)
. 一个函数需要vector<int>*
,我想将它传递给(2,6,87,251)
.
Can I just (safely) take the iterator ++foo.begin()
, convert it to a pointer and pass that to the function? Or use &foo[1]
?
我可以(安全地)使用迭代器++foo.begin()
,将其转换为指针并将其传递给函数吗?还是用&foo[1]
?
UPDATE:People suggest that I change my function to take an iterator rather than a pointer. That seems not possible in my situation, since the function I mentioned is the find
function of unordered_set<std::vector*>
. So in that case, is copying the n-1
elements from foo
into a new vector and calling find
with a pointer to that the only option? Very inefficient! It's like Shlemiel the painter, especially since i have to query many subsets: the last n-1
, then n-2
, etc. elements and see if they are in the unordered_set
.
更新:人们建议我更改函数以采用迭代器而不是指针。在我的情况下这似乎是不可能的,因为我提到的find
功能是unordered_set<std::vector*>
. 那么在这种情况下,是否将n-1
元素foo
从新向量中复制到一个新向量中并find
使用指向该向量的指针进行调用是唯一的选择?非常低效!这就像画家 Shlemiel 一样,尤其是因为我必须查询许多子集:最后一个n-1
、 thenn-2
等元素并查看它们是否在unordered_set
.
采纳答案by bk1e
That seems not possible in my situation, since the function I mentioned is the find function of
unordered_set<std::vector*>
.
在我的情况下这似乎是不可能的,因为我提到的函数是
unordered_set<std::vector*>
.
Are you using custom hash/predicate function objects? If not, then you must pass unordered_set<std::vector<int>*>::find()
the pointer to the exact vector that you want to find. A pointer to another vector with the same contents will not work. This is not very useful for lookups, to say the least.
您是否使用自定义哈希/谓词函数对象?如果没有,那么您必须将unordered_set<std::vector<int>*>::find()
指针传递给您要查找的确切向量。指向另一个具有相同内容的向量的指针将不起作用。至少可以说,这对于查找不是很有用。
Using unordered_set<std::vector<int> >
would be better, because then you could perform lookups by value. I think that would also require a custom hash function object because hash
does not to my knowledge have a specialization for vector<int>
.
使用unordered_set<std::vector<int> >
会更好,因为这样您就可以按值执行查找。我认为这也需要一个自定义的哈希函数对象,因为据hash
我所知并没有专门针对vector<int>
.
Either way, a pointer into the middle of a vector is not itself a vector, as others have explained. You cannot convert an iterator into a pointer to vector without copying its contents.
无论哪种方式,指向向量中间的指针本身都不是向量,正如其他人所解释的那样。您不能在不复制其内容的情况下将迭代器转换为指向向量的指针。
回答by Robocide
here it is, obtaining a reference to the coresponding pointer of an iterator use :
在这里,获取对迭代器使用的相应指针的引用:
example:
例子:
string my_str= "hello world";
string::iterator it(my_str.begin());
char* pointer_inside_buffer=&(*it); //<--
[notice operator * returns a referenceso doing & on a reference will give you the address].
[注意运算符 * 返回一个引用,因此在引用上执行 & 会给你地址]。
回答by Uri
If you can, a better choice may be to change the function to take either an iterator to an element or a brand new vector (if it does not modify).
如果可以,更好的选择可能是更改函数以将迭代器带到元素或全新的向量(如果它不修改)。
While you can do this sort of things with arrays since you know how they are stored, it's probably a bad idea to do the same with vectors. &foo[1]
does not have the type vector<int>*
.
虽然你可以用数组做这种事情,因为你知道它们是如何存储的,但对向量做同样的事情可能是一个坏主意。&foo[1]
没有类型vector<int>*
。
Also, while the STL implementation is available online, it's usually risky to try and rely on the internal structure of an abstraction.
此外,虽然 STL 实现可在线获得,但尝试依赖抽象的内部结构通常是有风险的。
回答by Chris Jester-Young
Your function shouldn't take vector<int>*
; it should take vector<int>::iterator
or vector<int>::const_iterator
as appropriate. Then, just pass in foo.begin() + 1
.
你的功能不应该采取vector<int>*
; 它应该采取vector<int>::iterator
或vector<int>::const_iterator
酌情。然后,只需传入foo.begin() + 1
.
回答by Macke
A vector is a container with full ownership of it's elements. One vector cannot hold a partial view of another, even a const-view. That's the root cause here.
向量是一个容器,拥有其元素的完全所有权。一个向量不能包含另一个向量的部分视图,即使是常量视图。这就是这里的根本原因。
If you need that, make your own container that has views with weak_ptr's to the data, or look at ranges. Pair of iterators (even pointers work well as iterators into a vector) or, even better, boost::iterator_range that work pretty seamlessly.
如果您需要,请制作您自己的容器,该容器具有对数据的weak_ptr 的视图,或查看范围。一对迭代器(甚至指针在向量中的迭代器也能很好地工作),或者更好的是 boost::iterator_range 可以无缝地工作。
It depends on the templatability of your code. Use std::pair if you need to hide the code in a cpp.
这取决于您的代码的模板性。如果需要在 cpp 中隐藏代码,请使用 std::pair。
回答by John Dibling
The direct answer to your question is yes. If foo is a vector, you can do this: &foo[1].
你的问题的直接答案是肯定的。如果 foo 是一个向量,你可以这样做:&foo[1]。
This only works for vectors however, because the standard says that vectors implement storage by using contigious memory.
然而,这只适用于向量,因为标准说向量通过使用连续内存来实现存储。
But you still can (and probably should) pass iterators instead of raw pointers because it is more expressive. Passing iterators does not make a copy of the vector.
但是您仍然可以(并且可能应该)传递迭代器而不是原始指针,因为它更具表现力。传递迭代器不会复制向量。
回答by Michael Burr
For example, my
vector<int> foo
contains (5,2,6,87,251). A function takesvector<int>*
and I want to pass it a pointer to (2,6,87,251).
例如,我的
vector<int> foo
包含 (5,2,6,87,251)。一个函数需要vector<int>*
,我想传递一个指向 (2,6,87,251) 的指针。
A pointer to a vector<int>
is not at all the same thing as a pointer to the elements of the vector.
指向vector<int>
a 的指针与指向向量元素的指针完全不同。
In order to do this you will need to create a new vector<int>
with just the elements you want in it to pass a pointer to. Something like:
为了做到这一点,您需要创建一个新的,vector<int>
其中只包含您想要传递指针的元素。就像是:
vector<int> tempVector( foo.begin()+1, foo.end());
// now you can pass &tempVector to your function
However, if your function takes a pointer to an arrayof int, then you can pass &foo[1]
.
但是,如果您的函数采用指向int数组的指针,那么您可以通过&foo[1]
.
回答by Ogre Psalm33
Use vector::front
, it should be the most portable solution. I've used this when I'm interfacing with a fixed API that wants a char ptr. Example:
使用vector::front
,它应该是最便携的解决方案。当我与需要字符 ptr 的固定 API 交互时,我使用了它。例子:
void funcThatTakesCharPtr(char* start, size_t size);
...
void myFunc(vector<char>& myVec)
{
// Get a pointer to the front element of my vector:
char* myDataPtr = &(myVec.front());
// Pass that pointer to my external API:
funcThatTakesCharPtr(myDataPtr, myVec.size());
}
回答by vivek sapru
Vector is a template class and it is not safe to convert the contents of a class to a pointer : You cannot inherit the vector class to add this new functionality. and changing the function parameter is actually a better idea. Jst create another vector of int vector temp_foo (foo.begin[X],foo.end()); and pass this vector to you functions
Vector 是一个模板类,将类的内容转换为指针是不安全的:您不能继承 vector 类来添加此新功能。而改变函数参数实际上是一个更好的主意。Jst 创建另一个 int 向量 temp_foo (foo.begin[X],foo.end()); 并将这个向量传递给你的函数
回答by Shocker
A safe version to convert an iterator to a pointer (exactly what that means regardless of the implications) and by safe I mean no worries about having to dereference the iterator and cause possible exceptions / errors due to end()
/ other situations
将迭代器转换为指针的安全版本(无论其含义如何),安全我的意思是不必担心必须取消引用迭代器并由于end()
/其他情况而导致可能的异常/错误
#include <iostream>
#include <vector>
#include <string.h>
int main()
{
std::vector<int> vec;
char itPtr[25];
long long itPtrDec;
std::vector<int>::iterator it = vec.begin();
memset(&itPtr, 0, 25);
sprintf(itPtr, "%llu", it);
itPtrDec = atoll(itPtr);
printf("it = 0x%X\n", itPtrDec);
vec.push_back(123);
it = vec.begin();
memset(&itPtr, 0, 25);
sprintf(itPtr, "%llu", it);
itPtrDec = atoll(itPtr);
printf("it = 0x%X\n", itPtrDec);
}
will print something like
会打印类似的东西
it = 0x0
it = 0x2202E10
它 = 0x0
它 = 0x2202E10
It's an incredibly hacky way to do it, but if you need it, it does the job. You will receive some compiler warnings which, if really bothering you, can be removed with #pragma
这是一种令人难以置信的 hacky 方式,但如果您需要它,它可以完成工作。你会收到一些编译器警告,如果真的打扰你,可以用#pragma