如何在不制作副本的情况下将`std :: string`转换为`std :: vector <unsigned char>`?

hkB*_*sai 7 c++ casting stdstring stdvector

我想调用一个库函数,其签名是:

bool WriteBinary(const std::vector<uint8_t> & DataToWrite);
Run Code Online (Sandbox Code Playgroud)

我有一个std::string变量,我想把它作为参数发送给它.

void WriteString(const std::string & TextData)
{
    // ...
    WriteBinary(TextData);  // <-- How to make this line work?
    // ...
}
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以直接发送std::string变量而无需复制它?

Mar*_*k B 11

没有办法做到这一点,因为两种类型的布局不能保证以任何方式相似.

最好的方法是修复WriteBinary使用"迭代器":

bool WriteBinary(const unsigned char* first, const unsigned char* last);
Run Code Online (Sandbox Code Playgroud)

或模板:

template <typename Iter>
bool WriteBinary(Iter first, Iter last);
Run Code Online (Sandbox Code Playgroud)

然后你可以将它用于字符串,向量或任何其他你喜欢的容器!

否则,您可以使用迭代器构造函数尽可能高效地执行复制:

WriteBinary(std::vector<uint8_t>(TextData.begin(), TextData.end()));
Run Code Online (Sandbox Code Playgroud)


Rei*_*ica 5

我担心这是不可能的.既没有string也没有vector允许它"采用"预先存在的缓冲区的构造函数.并且它很可能是a string和a 的内存布局vector不同,所以没有可能的转换.


Pix*_*ist 1

当然,您可以自由地破解自己以获得所需的结果。但是您应该准备好由同事或想要使用/维护/修改或移植您的代码的人进行摘要执行...

...别这样做!...

int main (void)
{
  std::string teststring("HERE IS A TEST");
  char * p = (char*)malloc(3*sizeof(char*) + sizeof(std::allocator<char>));
  std::allocator< std::allocator<char> > alloc_alloc;
  char * pa = p + 3*sizeof(char*);
  alloc_alloc.construct((std::allocator<char>*)pa);

  char const * cp = teststring.data();
  char const * * vec_it = (char const**)p;

  vec_it[0] = cp;
  vec_it[1] = cp + teststring.length();
  vec_it[2] = vec_it[1];

  std::vector<char> &a_vector = *((std::vector<char, std::allocator<char>>*)p);

  cout << a_vector.size() << " elements in vector!" << endl;

  for (std::vector<char>::iterator i=a_vector.begin(); i!=a_vector.end(); ++i) 
  {
    cout << *i;
  }
  cout << endl;
  // set char 8 to 66 = B
  a_vector[8] = 66;

  cout << teststring << endl;

}
Run Code Online (Sandbox Code Playgroud)

印刷

14 elements in vector!
HERE IS A TEST
HERE IS B TEST
Run Code Online (Sandbox Code Playgroud)

笔记:

正如评论中正确提到的,该解决方案依赖于向量具有以下数据布局,并要求字符串连续存储其数据(不知道这是否是由标准预先确定的)。

template <typename T>
class vector
{
  T* _first, _last, _end;
  std::allocator<T> _alloc;
};
Run Code Online (Sandbox Code Playgroud)