簡體   English   中英

現場對象創建與變量聲明

[英]Object creation on the spot vs variable declaration

我有以下代碼(將字符串拆分為一個向量),它在for_each循環的第二次迭代中給出了段錯誤:

std::string command = "Something something something";
std::sregex_token_iterator splitter {command.begin(), command.end(), std::regex{"\\s+"}, -1};
std::sregex_token_iterator splitter_end;
std::for_each(splitter, splitter_end, [&](std::ssub_match sm) {
    cmd.push_back(sm.str());
});

試圖理解發生了什么,我將正則表達式的聲明分離為命名變量,並開始工作:

std::string command = "Something something something";
std::regex rx {"\\s+"};
std::sregex_token_iterator splitter {command.begin(), command.end(), rx, -1};
std::sregex_token_iterator splitter_end;
std::for_each(splitter, splitter_end, [&](std::ssub_match sm) {
    cmd.push_back(sm.str());
});

任何人都可以向我解釋這個嗎?

我知道答案,但我不喜歡它。 我認為這可能是鏗鏘的缺陷。

std::sregex_token_iterator正在保存指向正則表達式的指針。

在第一個版本中,在構造splitter之后,將破壞匿名std::regex對象。 這會使splitter指向內存中的釋放空間。

在第二個版本中, rx將一直運行到塊結束。 這使得splitter指向適當的物體。


std::regex_token_iterator構造函數

template <class _BidirectionalIterator, class _CharT, class _Traits>
regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
                     const regex_type& __re, int __submatch,
                     regex_constants::match_flag_type __m)
: __position_(__a, __b, __re, __m),
_N_(0),
__subs_(1, __submatch)
{
    __init(__a, __b);
}

構造__position_類型std::regex_iterator

template <class _BidirectionalIterator, class _CharT, class _Traits>
regex_iterator<_BidirectionalIterator, _CharT, _Traits>::
regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
               const regex_type& __re, regex_constants::match_flag_type __m)
: __begin_(__a),
__end_(__b),
__pregex_(&__re),
__flags_(__m)
{
    _VSTD::regex_search(__begin_, __end_, __match_, *__pregex_, __flags_);
}

這是將__re的地址存儲在指針中。 一旦__re超出范圍, __re被破壞__position_留下一個懸空指針。


最后的說明

以下作品:

std::string command = "Something something something";
std::for_each(std::sregex_token_iterator{command.begin(), command.end(), std::regex{"\\s+"}, -1},
              std::sregex_token_iterator{},
              [&](std::ssub_match sm) {
    cmd.push_back(sm.str());
});

這是因為匿名std::regex的生命周期與匿名std::sregex_token_iterator對象相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM