std::string和std::vector<unsigned char>之间的std::move

19

我正在使用两个库。其中一个使用std::string进行输入和返回,而另一个则使用std::vector<unsigned char>

如果我能够从std::stringstd::vector<unsigned char>中获取底层数组,并将它们彼此之间移动而不进行过多的复制就好了。

目前我使用类似于以下的方法:

const unsigned char* raw_memory =
    reinterpret_cast<const unsigned char*>(string_value.c_str()),
std::vector<unsigned char>(raw_memory, raw_memory + string_value.size();

还有另一种方式:

std::string(
    reinterpret_cast<const char*>(&vector_value[0]),
    vector_value.size());

最好能定义一个:

std::string move_into(std::vector<unsigned char>&&);
std::vector<unsigned char> move_into(std::string&&);
2个回答

15

您可以使用迭代器初始化。请查看这里

编辑:为了避免您访问 ideone,我将代码粘贴在下面。但是依然保留链接,以便您可以自己进行代码操作。

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main() {
        string a = "Hello world";
        vector<unsigned char> v(a.begin(), a.end());
        for (int i= 0 ;i<  v.size(); ++i) {
           cout << v[i] << endl;
        }
        string s(v.begin(), v.end());
        cout << s << endl;
        return 0;
}

5
当然,就所需副本(他问题的所在)而言,这与他的解决方案没有任何不同,因此并未以任何方式回答他的问题。虽然比他的解决方案更加简洁,但仅仅写一条评论就足够了。 - Christian Rau
@Christian 为什么更干净?string& assign (const char* s, size_t n);应该执行memcpy,而template <class InputIterator> string& assign (InputIterator first, InputIterator last);则模拟它。 - Liviu

11

这是不可能的。

vectorstring类没有提供除了vectorstring本身以外的方法来窃取内容。它们不用于交换内容。

问题在于vectorstring可能具有完全不同的底层表示方式。通常在gcc中,string使用旧式的COW(Copy On Write)“优化”,这与典型的vector表示方式(通常只是三个指针/size_t属性的三元组)大不相同。

如果你正在处理原始字节,请责怪决定将它们放入string的库,并在可能的情况下进行重构。

否则:复制。不应该需要reinterpret_cast,因为charunsigned char之间有隐式的强制类型转换(现在默认情况下char通常是unsigned)。


1
C++11明确禁止写时复制,不是吗?除非他们将其纳入“只要其表现得像我们遵守了规范法律”的规定之下。我认为小字符串优化已经是一段时间以来的选择方式。 - Mahmoud Al-Qudsi

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