gpt4 book ai didi

c++ - std::vector 的指针运算

转载 作者:行者123 更新时间:2023-11-28 04:42:47 25 4
gpt4 key购买 nike

以前,我在一个具有接口(interface)的库中使用一些代码

void f( T* x );
void g( T* x );

在哪里

  • f 将用一些值填充 x 的第一个 m 条目(覆盖 x 中的任何内容)
  • g 将用一些值填充 x 的前 n 条目(覆盖 x 中的任何内容)

我想连接这两个值,所以我这样做了

void concat( T* x ){
f(x);
x += m;
g(x);
x += n;
...
}

实际上,我使用这样的指针运算连接了大约 10 个这样的函数。

现在我们正尝试使用不同的库来实现相同的目的。但是,新库有接口(interface)

void f_new( std::vector<T> & x );
void g_new( std::vector<T> & x );

同样,这些函数分别填充 x 的第一个 mn 元素(覆盖当前在 中的任何内容) x).此外,我必须创建一个带有签名的新 concat 函数

void concat_new( std::vector<T> & x  ){
// TODO
...
}

使用 vector 实现先前结果的最有效方法是什么?我能弄清楚如何做到这一点的唯一方法是在调用之间复制数据。

注意:我无法修改 concat_new、f_new 或 g_new 的签名

最佳答案

没有有效的方法可以做到这一点。

一个好的库应该使用迭代器。如果没有,您将不得不复制这些元素。

但是:如果您知道最终大小,则可以通过为目标 vector 保留空间来进行一些优化。

void concat( std::vector<T>& x ){
x.reserve(m+n+...);
f(x);

std::vector<T> buffer;
buffer.reserve(std::max({n, ...}));

g(buffer);
x.insert(x.end(), buffer.begin(), buffer.end());

...
}

通过重用 buffer,您至少可以跳过重新分配。


如果您可以更改 f 的签名,然后将其更改为

void f(std::vector<T>::iterator begin, std::vector<T>::iterator end) {
... // (should use 'end' at least to check the target size)
}

您始终可以使用包装器实现向后兼容性:

void f(std::vector<T>& x)
{
f(x.begin(), x.end());
}

然后使用

void concat( std::vector<T>& x) {
assert(x.size() >= m+n);
f(x.begin(), x.begin() + m);
g(x.begin() + m, x.begin() + m + n);
}

但要确保 x 足够大!

关于c++ - std::vector 的指针运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49873747/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com