简体   繁体   English

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

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

Given a pointer to an array of char, is it possible to construct a std::vector or boost::array from it, and avoiding memory copying? 给定一个char数组的指针,是否可以从中构造一个std :: vector或boost :: array,并避免内存复制?

Thanks in advance! 提前致谢!

Because vectors own their own allocators and storage alike, there is no way (for non primitive elements construction from move_iterator s could help a bit). 因为向量拥有自己的分配器和存储器,所以没有办法(对于非原始元素, move_iterator的构造可能会有所帮助)。

So assuming the goal is to get a true std::vector<char>& for the existing storage, you'll never succeed, not even with custom allocators¹. 因此,假设目标是获得一个真正的std::vector<char>&对于现有存储,你将永远不会成功,即使使用自定义分配器¹也是如此。


If you want a string, you can use boost::string_ref (in utility/string_ref.hpp ). 如果需要字符串,可以使用boost::string_ref (在utility/string_ref.hpp )。

Otherwise, you could use a 1-dimensional multi_array_ref (from Boost Multi Array) 否则,您可以使用1维multi_array_ref (来自Boost Multi Array)

1. Using string_ref 1.使用string_ref

This is definitely easiest: 这绝对是最简单的:

Live On Coliru 住在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 2. multi_array_ref

This is more versatile, and works "better" if you are not geared towards a string interface. 这是更多功能的,如果你不适合字符串界面,它会“更好”。

Live On Coliru 住在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());
}

Both examples print 两个例子打印

hello world

¹ specializing std::allocator<char> is too evil to consider and probably outright prohibited by the standard ¹专门化std::allocator<char>太难以考虑,可能完全被标准所禁止

An alternative without using boost would be std::reference_wrapper 不使用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);
}

Using struct S you can see that objects are not copied to the vector. 使用struct S可以看到对象未复制到向量。 So this should work well also for char . 所以这应该也适用于char

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM