如何在不复制的情况下从C数组构建std :: vector或boost :: array?

3
给定一个指向char数组的指针,是否可以从中构建std::vector或boost::array,并避免内存复制?
谢谢!

1
你可能正在寻找建议中的 std::array_view 或者 string_view,因为这是关于 char 的。 - chris
2个回答

6
因为向量拥有自己的分配器和存储,所以没有办法(对于非原始元素,从move_iterator构造可能会有所帮助)。
因此,假设目标是获得现有存储的真正std::vector<char>&,即使使用自定义分配器¹,也永远不会成功。
如果您需要一个字符串,可以使用boost::string_ref(在utility/string_ref.hpp中)。
否则,您可以使用一维的multi_array_ref(来自Boost Multi Array)
1. 使用string_ref
这肯定是最简单的: Live On Coliru
#include <boost/utility/string_ref.hpp>
#include <iostream>

using boost::string_ref;

int main() {
    char some_arr[] = "hello world";

    string_ref no_copy(some_arr);

    std::cout << no_copy;
}

2. multi_array_ref

这种方式更加灵活,如果你不需要使用字符串接口,那么它会“更好”地工作。

在Coliru上实时运行

#include <boost/multi_array/multi_array_ref.hpp>
#include <iostream>

using ref = boost::multi_array_ref<char, 1>;
using boost::extents;

int main() {
    char some_arr[] = "hello world";

    ref no_copy(some_arr, extents[sizeof(some_arr)]);

    std::cout.write(no_copy.data(), no_copy.num_elements());
}

这两个例子都会打印出来

hello world

¹专门使用std::allocator<char>太过危险,不被标准允许


作为礼貌,这是我回答这个问题的直播链接实验)。 - sehe
@dyp 我认为在那种情况下使用std::vector没有真正的价值(由于自定义分配器,类型已经是不同的)。但从技术上讲,这是第三个选项(取决于您如何狭义地定义std::vector<T> :))。 - sehe
祝你好运,也过 void api2::foo(std::vector<char> const&); - 这就是我说“在那里使用 std::vector 没有真正价值”的原因。我认为这种情况是 OP 面临的情况。实际上,他应该要求库开发人员修复 API,使其不那么侵入性 :) - sehe
@dyp 我已经按照你的要求更明确地发出了这个警告。 - sehe

1

如果不使用boost,另一种选择是std::reference_wrapper

#include <vector>
#include <iostream>
#include <functional>

using namespace std;

struct S
{
    S() : val(0) {}
    S(int val_) : val(val_) {}
    S(const S& other) : val(other.val) {
        cout << "copy" << endl;
    }

    int val;
};


int main()
{
    char a[] = "Hello";
    vector<reference_wrapper<char>> v(a, a+5);

    S vS[] = {S(1), S(2), S(3)};

    vector<S> v_copy(vS, vS + 3);
    vector<reference_wrapper<S>> v_nocopy(vS, vS+3);
}

使用结构体S,你可以看到对象并没有被复制到向量中。因此,这对于char也应该很好用。

2
这很好。重要的是要意识到,从内存角度来看,你现在实际上是在处理一个 char* 向量,这可能会对性能产生非常严重的影响。这就是我不在这里点赞的原因,因为我认为上下文都是关于通过消除分配/复制来最大化性能的。 - sehe
@sehe 听起来没错。只是想指出,至少对于对象而言这值得注意。 - Miki

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