使用给定的数组初始化 std::vector 而不使用 std::allocator

Initialize std::vector with given array without std::allocator

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

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

我从另一个已经分配的库收到一个非常大的 C 风格数组:

int* data = bar();

有什么方法可以让我在不分配和复制每个元素的情况下将 data 传递给 foo 吗? data 非常大,因此我想尽可能避免复制和分配。

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

我知道我可能在寻求魔法,但如果可能的话那就太好了。当然,如果 foo 宁愿选择 std::span 这也不是问题。

Is there any way for me to pass on data to foo without allocating and copying each element?

不行,前提是没办法避免。

通过改变前提,有两种替代解决方法:

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

魔法

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

我们可以强行访问一个vector的容器

以g++为例。它使用三个受保护的指针 _M_start_M_finish_M_end_of_storage 来处理存储。所以我们可以在构造函数和析构函数中创建一个派生的class,即sets/resets指向return of vaule bar()的指针。

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));