2012-08-16 68 views
3

考慮到簽名者std::regex_match( std::string const&, std::smatch& match, std::regex const& re)的C++ 11函數, 是第一個參數生命週期的約束?我不覺得 任何,但是當我執行以下程序(用VC++ 2010編譯, 迭代器調試有效):對std :: regex_match(和std :: regex_search)參數生存期的約束

int 
main() 
{ 
    std::string a("aaa"); 
    std::string c("ccc"); 
    std::regex re("aaa(.*)ccc"); 
    std::smatch m; 
    if (std::regex_match(a + "xyz" + c, m, re)) { 
     std::cout << m[0] << std::endl; 
     std::cout << m[1] << std::endl; 
    } 
    return 0; 
} 

崩潰,無疑是因爲在msub_match只保留 迭代器串,而不是副本。我在找不到我的代碼的標準 中找不到任何東西。

FWIW:它也不在boost::regex中工作,這就是 std::regex所依據的。 (當然,升壓沒有記錄與問候壽命任何 約束要麼)

最後,我想我的問題是:我應該在DR發送到 標準組織,或一個錯誤報告到微軟?

+0

我會發送DR。現在,DR應該是另一個問題。這些選項可能只是記錄或提供一個需要右值引用的重載,以便*看起來*正確的簡單代碼行爲正確。 [我傾向於文檔方法] – 2012-08-16 17:00:57

+0

@DavidRodríguez-dribeas在什麼基礎上?標準中有許多函數需要引用,並且所需的生命週期永遠不會超過函數本身。基於什麼(除了Boost的做法),我們是否假設這不是這個意圖? – 2012-08-16 17:05:03

+0

好的,所以你在說這可能是實現中的一個錯誤,並且標準可能被設計成複製參數。是的,這是第三種方法:) – 2012-08-16 17:10:08

回答

3

我不記得在採用tr1::regexstd::regex期間對這種可能性的任何討論,所以我認爲它根本沒有考慮。事後看來,這肯定是我們應該預見的陷阱。關閉我的頭頂部,一個需要std::string&&的超負荷將表示涉及臨時,並且需要一個副本。所以我會把它報告給標準委員會。 (全面披露:我寫的Dinkumware的實現,這是微軟的船舶)

+0

而且您可能將其基於Boost,它具有相同的問題(包括缺少關於任何要求的文檔)。這通常不是一個問題,因爲你通常不會嘗試匹配臨時對象。 (另一方面,我可以很容易地看到匹配一個循環的本地字符串,循環外有'smatch',並在循環結束後使用。) – 2012-08-16 17:09:06

+1

@JamesKanze - 它不是基於Boost。在這方面只是同時缺乏遠見。 – 2012-08-16 17:10:08

1

這種超負荷的regex_match規範指出,它(28.11.2 [re.alg.match/6):

返回:regex_match(s.begin(), s.end(), m, e, flags)

上有此重載沒有額外的要求,以及它所代表的重載只需要一個迭代器範圍 - 有沒有辦法爲它保留臨時串活着,因爲它不甚至不知道那裏是一個活着的字符串。

STL'sregex presentation at C++Now '12期間討論過這個問題。有人建議可以在規範中增加額外的重載,以便捕獲右值字符串參數(例如basic_string<...>&&),這會給出一個很好的編譯錯誤,而不是此運行時錯誤。雖然庫規格不包括那些重載,但我沒有看到這個缺陷報告。

+0

這個問題不僅僅與rvalues有關。考慮在循環外聲明一個'smatch',並在循環內調用'regex_match',並在循環內部定義一個字符串。問題很複雜:它可以工作(通過在匹配的情況下保留字符串的副本),因此可能需要它工作。 – 2012-08-16 17:12:47

+1

@JamesKanze - 好點。但其含義是,圖書館一般不能檢測到這一生問題。保持一個字符串的副本是相當重量級的,所以我在這一點上的傾向將是保持原樣,並告訴人們「不要這樣做」。但是,我當然不會爲委員會發言。 – 2012-08-16 17:15:15

+0

@JamesKanze:我沒有看到與編譯時無法檢測到的其他生存期問題有什麼不同:{std :: vector v; return v.begin(); }'是格式良好的代碼,並且無法檢測(在所有情況下)函數返回後返回的迭代器失效。至少一個被刪除的右值超載將有助於發現明顯的誤用。在我看來,'match_results'已經被充分指定:它只處理迭代器,這是一個很好的指示,應該注意它們指向的範圍的生命週期。 – 2012-08-16 17:20:20

相關問題