<CString> 使用 C++ / STL 将 std::vector 展平为multi_sz的推荐方法是什么

What is the recommended way to flatten a std::vector<CString> to a multi_sz using C++ / STL

本文关键字:sz multi 是什么 方法 C++ 使用 gt STL vector lt std      更新时间:2023-10-16

我想写一个字符串列表(ATL::CString)存储在std::vector到Windows注册表中的REG_MULTI_SZ值。我知道如何在纯C中做到这一点(迭代一次以获得总长度,分配缓冲区,将字符串复制到以""分隔的缓冲区)。

知道我尝试了以下使用STL(对不起,我必须使用VS2010"for each"):

std::vector<TCHAR> multiline_sz;
for each ( CString entry in myStringList )
{
   TCHAR* buf = entry.GetBuffer();
   multiline_sz.insert(multiline_sz.end(), &buf[0], &buf[entry.GetLength()]);
   multiline_sz.push_back(L'');
}
multiline_sz.push_back(L'');

这个工作,但我想知道是否有一个更优雅或更快的方式使用STL。

我建议使用 CString::GetString() (而不是CString::GetBuffer()),因为它返回指向只读访问的以null结尾的字符串的指针。

此外,还要注意CString::GetBuffer()需要匹配CString::ReleaseBuffer()调用。

我也会简化你的代码,没有不必要的&buf[0], &buf[<index>]语法。

// Your pseudo code: 
// for each ( CString entry in myStringList )
{
  multiline_sz.insert(
      multiline_sz.end(), 
      entry.GetString(), // <-- current string's start
      entry.GetString() + entry.GetLength() + 1 // <-- include terminating NUL
  );
}

作为进一步的优化,您可以扫描整个输入字符串列表,并预先计算所需的长度,并在vector::insert()调用之前调用std::vector::reserve()来预先分配向量中的空间。这将在插入过程中节省一些重新分配和复制。


注:如果想用c++ 11 range-for循环遍历std::vector<CString>,可以使用以下语法:

for (const auto& entry : myStringList) 

CString::GetBuffer()已经是零终止,所以执行

for each ( CString entry in myStringList )
{
   TCHAR const* buf = entry.GetBuffer();
   multiline_sz.insert(multiline_sz.end(), &buf[0], &buf[entry.GetLength()+1]);
}