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

How to construct a std::vector or a boost::array from a C array without copying?

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

提前致谢!

因为向量拥有自己的分配器和类似的存储,所以没有办法(对于来自 move_iterators 的非基本元素构造可能会有所帮助)。

因此假设目标是为现有存储获得真正的 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

如果您不适合字符串接口,这更通用,并且 "better" 可以工作。

Live On 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> 太邪恶了,无法考虑并且可能被标准完全禁止

不使用 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);
}

使用 struct S你可以看到对象没有被复制到向量中。所以这也适用于 char.