使用给定的数组初始化std::vector,而不使用std::分配器



我使用的是一个外部库,它提供了一个具有以下接口的函数:

void foo(const std::vector<int>& data);

我从另一个已经分配的库中收到了一个非常大的C样式数组:

int* data = bar();

有没有什么方法可以在不分配和复制每个元素的情况下将data传递给foodata非常大,因此如果可能的话,我希望避免复制和分配。

我本可以使用分配器,但foo不是分配器的模板,所以我认为这是不可能的。

我知道我可能在请求魔法,但如果可能的话,那就太好了。当然,如果foo采用std::span,这将不是问题。

魔术

这个答案很神奇,取决于编译器的实现。

我们可以强制访问矢量的容器。

以g++为例。它使用三个受保护的指针_M_start_M_finish_M_end_of_storage来处理存储。因此,我们可以创建一个派生类,在构造函数和析构函数中设置/重置指向vaulebar()返回的指针。

g++的示例代码:

static_assert(__GNUC__ == 7 && __GNUC_MINOR__ == 5 && __GNUC_PATCHLEVEL__ == 0);
class Dmy: public std::vector<int>
{
public:
Dmy(int *b, int *e)
{
_M_impl._M_start = b;
_M_impl._M_finish = e;
_M_impl._M_end_of_storage = _M_impl._M_finish;
}
~Dmy()
{
_M_impl._M_start = 0;
_M_impl._M_finish = 0;
_M_impl._M_end_of_storage = 0;
}
};
foo(Dmy(data, end_of_data));

有什么方法可以在不分配和复制每个元素的情况下将数据传递给foo吗?

不,在这个前提下,没有办法避免它。

通过更改前提有两种替代解决方案:

  • 更改其他库以返回向量
  • foo更改为不需要矢量。正如您所指出的,std::span可能是一个合理的选择

最新更新