如何在不复制的情况下从 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_iterator
s 的非基本元素构造可能会有所帮助)。
因此假设目标是为现有存储获得真正的 std::vector<char>&
,您将永远不会成功,即使使用自定义分配器也不会成功¹。
如果你想要一个字符串,你可以使用boost::string_ref
(在utility/string_ref.hpp
)。
否则,您可以使用一维 multi_array_ref
(来自 Boost Multi Array)
1。使用 string_ref
这绝对是最简单的:
#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" 可以工作。
#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
.
给定一个指向 char 数组的指针,是否可以从中构造一个 std::vector 或 boost::array,并避免内存复制?
提前致谢!
因为向量拥有自己的分配器和类似的存储,所以没有办法(对于来自 move_iterator
s 的非基本元素构造可能会有所帮助)。
因此假设目标是为现有存储获得真正的 std::vector<char>&
,您将永远不会成功,即使使用自定义分配器也不会成功¹。
如果你想要一个字符串,你可以使用boost::string_ref
(在utility/string_ref.hpp
)。
否则,您可以使用一维 multi_array_ref
(来自 Boost Multi Array)
1。使用 string_ref
这绝对是最简单的:
#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" 可以工作。
#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
.