C++ 访问stringstream对象的关联字符串

C++ 访问stringstream对象的关联字符串,c++,C++,我正在尝试访问stringstream对象的关联字符串并保留迭代器,但不知道这是否安全。代码如下: stringstream HTMLss; // string stream of HTML document // ... (load up HTMLss with HTML) const string & HTMLstr = HTMLss.str(); // grab reference to associated string string::const

我正在尝试访问stringstream对象的关联字符串并保留迭代器,但不知道这是否安全。代码如下:

  stringstream HTMLss;   // string stream of HTML document

  // ... (load up HTMLss with HTML) 

  const string & HTMLstr = HTMLss.str();   // grab reference to associated string 
  string::const_iterator begin,end;
  begin = HTMLstr.begin();                 // grab iterators to that string as well
  end = HTMLstr.end();
  boost::match_results<std::string::const_iterator> matches;

  // do some processing, updating the iterators along the way
  while( boost::regex_search(begin, end, matches, metaexp) )
    {
      string key( matches[1].first, matches[1].second );
      string raw_val( matches[2].first, matches[2].second );

      // ... some processing which does NOT manipulate HTMLss stringstream in any way

      begin = matches[2].second;   // updating the iterator
    }
stringstream HTMLss;//HTML文档的字符串流
// ... (用HTML加载HTMLS)
常量字符串&HTMLstr=HTMLss.str();//抓取对关联字符串的引用
字符串::常量迭代器开始、结束;
begin=HTMLstr.begin();//还可以获取该字符串的迭代器
end=HTMLstr.end();
匹配结果匹配;
//进行一些处理,沿途更新迭代器
while(boost::regex_搜索(开始、结束、匹配、metaexp))
{
字符串键(匹配[1]。首先,匹配[1]。其次);
字符串原始值(匹配项[2]。第一,匹配项[2]。第二);
//…某些处理不会以任何方式操作HTMLss stringstream
begin=匹配[2]。第二;//更新迭代器
}

我的问题是——这样做安全吗?是否可以假设可以保留/更新指向stringstream对象的关联字符串的迭代器,并且行为将是正确的?没有对任何字符串流函数的其他调用。如何知道这是否安全

这是安全的,但原因可能比你想象的要多
HTMLss.str()
返回内部字符串的副本,该副本绑定到常量引用。按照C++规则,绑定到本地const引用的临时项具有引用的生存期。因此,您发布的代码基本上与此等效:

string HTMLstr = HTMLss.str();

唯一的区别是这个版本可以调用复制构造函数。不过,这个调用可能会被优化掉。

仔细看看stringstream的方法。它返回字符串的副本,而不是对字符串对象的引用。因此,从理论上讲,只要您自己不更改字符串,您的迭代器就不会失效。

这将返回一个临时值,其生存期扩展到HTMLstr的范围:

const string & HTMLstr = HTMLss.str();
因为这是HTMLss缓冲区的副本,所以以后对HTMLss所做的任何更改都不会反映出来,但只要HTMLstr在范围内,就可以保留和使用HTMLstr的迭代器

但是,您也可以将HTMLstr设置为非引用,但可以根据需要保留常量(或删除它):

const string HTMLstr = HTMLss.str();

保持常量确实减少了使迭代器无效的方法,但在原始代码中也没有问题。

只要在存储迭代器和使用迭代器之间不做任何使迭代器无效的事情,这是安全的。也就是说,不建议存储它们,而是直接在使用它们的地方使用它们(在本例中,在regex_搜索调用中)。只是一个样式备注:您在一行上用逗号(=坏样式)在声明的正下方声明两个
常量迭代器(
begin
end
),您正在分配/初始化它们。最好是:
string::const_iterator begin=HTMLstr.begin();string::const_迭代器end=HTMLstr.end()(在两行上)。这不太容易出错,并且在代码方面是等效的。