C++中将float*数组作为std::vector<float>的引用传递

4

我想创建一个std::vector<float> vpd,它将是一个对float*的引用。

float * old = new float[6];
for (int i = 0; i < 6; i++)
{
    old[i] = i;
}
vector<float> vpd(6);
auto refasd = &*vpd.begin();
*refasd = *old;
vpd[0] = 23;
cout << old[0] << endl;

如果我想从cout中获取23,应该如何修改代码?

你可能在寻找这个: https://dev59.com/snE95IYBdhLWcg3wJKl_ - uceumern
这是关于告诉向量使用您“预分配”的缓冲区而不是向量内部管理的缓冲区,还是仅仅想用float*类型来引用向量内部缓冲区? - Stephan Lechner
也许你的意思是 vpd[0] = 23; *old = *refasd; - M.M
5个回答

5
你不能这样做。`std::vector`不是为了接管原始指针而设计的。
也许你可以使用`std::unique_ptr<float[]>`,但更好的解决方案是直接使用`std::vector`。

5
作为替代方案,您可以使用 std::span (C++20)。
float* old = new float[6];
std::iota(old, old + 6, 0);
std::span<float> vpd(old, 6);
vpd[0] = 23;
std::cout << old[0] << std::endl;
delete[] old;

2
来自未来的加一。span 是否拥有内存,即 delete[] 是否故意省略? - Bathsheba
如果我没记错的话,Span并不拥有内存,所以是的,缺少了delete[] - rubenvb

4

你也可以创建一个vectorstd::reference_wrapper对象,这些对象引用原始的float数组 - 无论是std::vector<float>还是newfloat*。以下是一个示例:

vector<std::reference_wrapper<float>> vpd(old, old + 6); // ¹

vpd[0].get() = 23.f;

cout << old[0] << endl; // prints 23

¹) 感谢@StoryTeller指出vpd可以直接初始化。


1
我不确定你是否需要使用 std::transform。如果我没记错的话,std::vector<std::reference_wrapper<float>> vpd(old, old + 6); 应该可以直接使用。 - StoryTeller - Unslander Monica
@StoryTeller 确实,这是一个不错的改进! - lubgr

2
由于 std::vector 有其自己的内存结构,所以您无法将 vector<float> 或者是 vector<float*> 映射到一个浮点数数组上。但是,您可以将每个向量项映射到一个数组项上。
float* old = new float[6];
for (int i = 0; i < 6; i++)
{
    old[i] = i;
}
vector<float*> vpd(6);
int i = 0;
for (auto it = vpd.begin(); it != vpd.end(); it++)
{
    *it = &old[i++];
}
*vpd[0] = 23;
*vpd[2] = 45;
cout << old[0] << endl << old[2] << endl;    

输出

23
45

@LightnessRacesinOrbit,您能否详细解释一下? - serge
1
现在你谈论的是创建这些元素的成本,而不是访问它们的成本。但答案仍然是肯定的。 - Lightness Races in Orbit
我的意思是在创建对象后访问的成本。 - serge
非常有趣的点,我认为如果你能呈现一个能够展示差异的小测试就好了。例如,两个包含100万个对象的向量。我也会尝试进行测试。 - serge
@LightnessRacesinOrbit非常好的观点,谢谢。我的测试也证实了 - serge
显示剩余9条评论

0
根据C++的版本,您将有一些选项(如果我理解问题的话): 如果您使用的是旧版C++而不是C++11,则在此情况下,我会将std::vector声明为:
// then you really need to make sure u delete the memory as well
std::vector<float*> vpd(6); 

如果您使用的是c++11或更高版本,我建议使用std::share_ptr或std::unique_ptr,具体取决于您是否想共享内存空间。这样可以确保内存被自动删除,而无需执行“delete float *;”,非常方便。

您可以在以下链接中了解std::shared_ptr:https://en.cppreference.com/w/cpp/memory/shared_ptr,以及std::unique_ptr:https://en.cppreference.com/w/cpp/memory/unique_ptr

// For unique_ptr
std::vector<std::unique_ptr<float>> vpd(6);
// for std::shared_ptr
std::vector<std::shared_ptr<float>> vpd(6);

我会建议你如果可以的话,使用unique_ptr而不是shared_ptr,因为shared_ptr在确保内存空间被删除之前有一些额外的复杂性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接