我有std::vector
个n
元素。现在我需要将一个指针传递给一个函数的最后n-1
个元素的向量。
例如,我的vector<int> foo
包含(5,2,6,87,251)
。函数需要vector<int>*
,我想传递一个指向(2,6,87,251)
的指针。
我可以(安全地)使用迭代器++foo.begin()
,将其转换为指针并将其传递给函数吗?或者使用&foo[1]
?
UPDATE:人们建议我更改我的函数以获取迭代器而不是指针。这似乎在我的情况下是不可能的,因为我提到的函数是find
的{{1}}函数。那么在这种情况下,是将unordered_set<std::vector*>
元素从n-1
复制到一个新向量中,并使用指向唯一选项的指针调用foo
?非常低效!这就像画家Shlemiel,特别是因为我必须查询许多子集:最后find
,然后是n-1
等元素,看看它们是否在n-2
。
答案 0 :(得分:80)
这里是,获取对迭代器使用的相应指针的引用:
示例:
string my_str= "hello world";
string::iterator it(my_str.begin());
char* pointer_inside_buffer=&(*it); //<--
[通知运营商*返回参考这样做&amp;在引用上会给你地址]。
答案 1 :(得分:8)
在我的情况下似乎不可能,因为我提到的功能是
unordered_set<std::vector*>
的查找功能。
您使用的是自定义哈希/谓词函数对象吗?如果没有,那么您必须将unordered_set<std::vector<int>*>::find()
指针传递给您想要找到的确切向量。指向具有相同内容的另一个向量的指针将不起作用。至少可以说,这对于查找不是很有用。
使用unordered_set<std::vector<int> >
会更好,因为您可以按值执行查找。我认为这还需要一个自定义哈希函数对象,因为hash
据我所知不具备vector<int>
的特化。
无论哪种方式,指向矢量中间的指针本身不是矢量,正如其他人所解释的那样。您无法将迭代器转换为指向vector的指针而不复制其内容。
答案 2 :(得分:6)
如果可以,更好的选择可能是更改函数以将元素的迭代器或全新的向量(如果它不修改)。
虽然您可以使用数组执行此类操作,因为您知道它们是如何存储的,但使用向量执行相同操作可能是个坏主意。 &foo[1]
没有vector<int>*
类型。
此外,虽然在线提供STL实现,但尝试依赖抽象的内部结构通常存在风险。
答案 3 :(得分:3)
你的功能不应该vector<int>*
;应视情况采用vector<int>::iterator
或vector<int>::const_iterator
。然后,只需传入foo.begin() + 1
。
答案 4 :(得分:3)
vector是一个拥有其元素完全所有权的容器。一个向量不能保持另一个向量的局部视图,甚至是const视图。这是根本原因。
如果您需要,请创建自己的容器,其中包含对数据的weak_ptr视图,或查看范围。一对迭代器(甚至指针在迭代器中很好地作为迭代器),或者更好的是,boost :: iterator_range可以非常无缝地工作。
这取决于代码的模板性。如果需要隐藏cpp中的代码,请使用std :: pair。
答案 5 :(得分:2)
你问题的直接答案是肯定的。如果foo是一个向量,你可以这样做:&amp; foo [1]。
这仅适用于矢量,因为标准表示矢量通过使用可靠的存储器来实现存储。
但你仍然可以(并且可能应该)传递迭代器而不是原始指针,因为它更具表现力。传递迭代器不会复制矢量。
答案 6 :(得分:1)
例如,我的
vector<int> foo
包含(5,2,6,87,251)。函数需要vector<int>*
,我想传递一个指向(2,6,87,251)的指针。
指向vector<int>
的指针与指向向量元素的指针完全不同。
为了做到这一点,你需要创建一个新的vector<int>
,只需要你想要的元素来传递指针。类似的东西:
vector<int> tempVector( foo.begin()+1, foo.end());
// now you can pass &tempVector to your function
但是,如果你的函数使用指向int的数组的指针,那么你可以传递&foo[1]
。
答案 7 :(得分:1)
使用vector::front
,它应该是最便携的解决方案。当我与一个需要char 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());
}
答案 8 :(得分:0)
如果你的函数真的需要vector<int> *
(指向向量的指针),那么你应该传递&foo
,因为那将是一个指向向量的指针。显然,这不会简单地解决你的问题,但你不能直接将迭代器转换为向量,因为迭代器地址处的内存不会直接寻址有效的向量。
您可以通过调用vector constructor:
来构建新的向量template <class InputIterator> vector(InputIterator, InputIterator)
这通过复制两个迭代器之间的元素来构造一个新的向量。你会大致使用它:
bar(std::vector<int>(foo.begin()+1, foo.end());
答案 9 :(得分:0)
我没有测试过这个,但你可以使用一组迭代器吗?每个迭代器对都代表序列向量的开始和结束迭代器。 E.g:
typedef std::vector<int> Seq;
typedef std::pair<Seq::const_iterator, Seq::const_iterator> SeqRange;
bool operator< (const SeqRange& lhs, const SeqRange& rhs)
{
Seq::const_iterator lhsNext = lhs.first;
Seq::const_iterator rhsNext = rhs.first;
while (lhsNext != lhs.second && rhsNext != rhs.second)
if (*lhsNext < *rhsNext)
return true;
else if (*lhsNext > *rhsNext)
return false;
return false;
}
typedef std::set<SeqRange, std::less<SeqRange> > SeqSet;
Seq sequences;
void test (const SeqSet& seqSet, const SeqRange& seq)
{
bool find = seqSet.find (seq) != seqSet.end ();
bool find2 = seqSet.find (SeqRange (seq.first + 1, seq.second)) != seqSet.end ();
}
显然,这些载体必须像以前一样保存在其他地方。此外,如果修改了序列向量,则必须删除该集合中的条目并重新添加,因为迭代器可能已更改。
乔恩
答案 10 :(得分:0)
Vector是一个模板类,将类的内容转换为指针是不安全的: 您无法继承vector类以添加此新功能。 并且更改函数参数实际上是一个更好的主意。 Jst创建另一个int向量 vector temp_foo(foo.begin [X],foo.end()); 并将此向量传递给函数
答案 11 :(得分:0)
将迭代器转换为指针的安全版本(正是这意味着无论其含义如何)并且安全我的意思是不必担心必须取消引用迭代器并导致由#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);
}
/引起的可能的异常/错误其他情况
#pragma
将打印类似
的内容it = 0x0
it = 0x2202E10
这是一种令人难以置信的hacky方式,但如果你需要它,它就能完成这项工作。您将收到一些编译器警告,如果真的困扰您,可以使用 <ul class="nav nav-tabs">
<li class="active"><a href="#One" data-toggle="tab">First</a></li>
<li class=""><a href="#Two" data-toggle="tab">Second</a></li>
</ul>
<div id="tabContent" class="tab-content">
<div class="tab-pane fade" id="One">
//Its works fine,and assigns the value to input field.
<input type="text" value="{{($row->value== 1) ?'test':'')}}" />
</div>
<div class="tab-pane fade" id="Two">
//value is not assigned to input field though condition is true.
<input type="text" value="{{($row->value== 1) ?'test':'')}}" />
</div>
</div>
答案 12 :(得分:0)
std::vector<int> v;
:
auto it=v.end();
auto ptr=v.data()+std::distance(v.begin(),it);