我有一个关于onstack创建数组的生命周期以及将它们转换为c ++向量的问题。对于前者,我有两个功能:
void getVector()
{
auto myVector = createVectorFromArray();
}
vector<float> createVectorFromArray()
{
float myArr[10];
readDataFromSomewhere(myArr, 10); //some read data function with signature void(float*, size_t)
vector<float> resVector;
resVector.assign(myArr, myArr+10);
return resVector;
}
据我所知,当我们离开函数 createVectorFromArray 时,阵列 myArr 将被终止。因此函数 getVector 中向量 myVector 的迭代器将指向无处。我是对的,还是以另一种方式工作?在这种情况下,如何从数组中更好地生成向量以从函数返回?
谢谢!
答案 0 :(得分:3)
您可以像这样重写createVectorFromArray
,并且在将数组分配给矢量时不会有任何麻烦:
vector<float> createVectorFromArray()
{
vector<float> resVector(10);
readDataFromSomewhere(&resVector[0], resVector.size());
return resVector;
}
std::vector
是连续的内存容器,因此您可以将它用作普通旧C函数的接口
答案 1 :(得分:2)
这个答案旨在讨论各种方法,解释它们,并将它们置于上下文中。
vector<float> createVectorFromArray()
{
// data copied once
float myArr[10];
readDataFromSomewhere(myArr, 10);
// vectors are lightweight handles. zero-cost construction
// since the optimiser will see that the next statement assigns to
// the vector
vector<float> resVector;
//
// data copied twice
//
resVector.assign(myArr, myArr+10);
//
// it's almost guaranteed that RVO will elide this copy. As of c++17
// it's a guarantee. Returning the vector is fine
return resVector;
}
问题:
vector<float> createVectorFromArray()
{
// Will allocate space and
// default-initialise the floats (i.e. they won't be initialised)
vector<float> resVector(10);
//
// one data copy. perfectly safe and idiomatic.
// std::addressof expressed intent clearly.
//
readDataFromSomewhere(std::addressof(resVector[0]), resVector.size());
//
// it's almost guaranteed that RVO will elide this copy. As of c++17
// it's a guarantee. Returning the vector is efficient.
return resVector;
}
问题:
...更好
void createVectorFromArray(vector<float>& resVector)
{
//
// if resVector has been used before and has a capacity() of 10
// or more, no memory allocation necessary
//
resVector.resize(10);
// one copy of data
readDataFromSomewhere(std::addressof(resVector[0]), resVector.size());
}
问题:
我如何在选项2和3之间进行选择?
选项2更具可读性(恕我直言),但如果在循环中使用则会很昂贵。所以对于一次性,我会去那。
如果我在循环中将数据读入缓冲区,我可能希望避免不必要的内存分配。因此,重新使用向量的容量将是明智之举。
e.g。
std::vector<float> buf;
while (thereIsMoreData())
{
createVectorFromArray(buf); // option 3
useTheData(buf);
// data no longer needed, so we can re-use the vector
}
备选方案:
while (thereIsMoreData())
{
// the passing of the vector is efficient, particularly as of c++11
// however, we still suffer one memory allocation per loop.
// probably undesirable in a high performance environment.
useTheData(createVectorFromArray()); // option 2
}
...最后
提供两者。允许用户按照他/她的意愿使用高效方法或“可读”方法
void createVectorFromArray(vector<float>& resVector)
{
//
// if resVector has been used before and has a capacity() of 10
// or more, no memory allocation necessary
//
resVector.resize(10);
// one copy of data
readDataFromSomewhere(std::addressof(resVector[0]), resVector.size());
}
// overload
std::vector<float> createVectorFromArray()
{
std::vector<float> result;
createVectorFromArray(result);
return result;
}
答案 2 :(得分:0)
int checkBoxWidth = foregroundHeight / 12.0;
int checkBoxHeight = foregroundHeight / 12.0;
UIButton* checkBox = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, checkBoxWidth, checkBoxHeight)];
//[checkBox setBackgroundImage:[Utility getEmptyCheckBoxOutIcon] forState:UIControlStateNormal];
//[checkBox setBackgroundImage:[Utility getCheckBoxOutIcon] forState:UIControlStateSelected];
[checkBox setImage:[Utility getEmptyCheckBoxOutIcon] forState:UIControlStateNormal];
[checkBox setImage:[Utility getCheckBoxOutIcon] forState:UIControlStateSelected];
checkBox.layer.borderWidth = 1.0;
checkBox.layer.borderColor = [Utility primaryColor].CGColor;
checkBox.layer.cornerRadius = cornerRadius;
[switchView addSubview:checkBox];
此处将std::vector::assign
的内容复制到myArr
,因此当resVector
超出范围并返回myArr
时,它就不会重要但仍将包含值。
更简单的方法是将resVector
传递给myArr, myArr + 10
构造函数,如下所示:
vector
正如另一个答案所说,你实际上可以像这样完全摆脱阵列:
float myArr[10];
readDataFromSomewhere(myArr, 10);
vector<float> resVector(myArr, myArr + 10);
return resVector;