2012-11-21 33 views
4

Boost的find_first算法是C的strstr()的各式的等價物,但爲什麼在草堆—的搜索空間—得到傳過來的非const參考?匹配範圍是在單獨的iterator_range對象中返回的,因此它不是通過引用輸出的問題。爲什麼boost :: find_first對其輸入採取非const引用?

它可以防止由make_iterator_range創建的臨時範圍的調用。

const std::string str("haystack"); 
const std::string findstr("stack"); 

boost::sub_range<const std::string> match = boost::algorithm::find_first(
     boost::make_iterator_range(str), 
     boost::make_iterator_range(findstr)); 

相反,表示源範圍內的局部變量必須顯式創建:

const std::string str("haystack"); 
const std::string findstr("stack"); 

boost::sub_range<const std::string> haystack = boost::make_iterator_range(str); 

boost::sub_range<const std::string> match = boost::algorithm::find_first(
     haystack, 
     boost::make_iterator_range(findstr)); 

(這同樣適用於其他功能在boost/algorithm/string/find.hpp,即findifind_firstfind_lastifind_lastfind_nth。 ,ifind_nthfind_headfind_tail & find_token)。

回答

10

這是爲了確保在致電find_first後返回的範圍仍然有效。

雖然最初的情況下以上就可以了,下面將導致match指向一個破壞臨時字符串:

boost::sub_range<const std::string> match = boost::algorithm::find_first(
     boost::make_iterator_range(std::string("haystack"), 
     boost::make_iterator_range(std::string("stack")); 

要求該乾草堆是非const防止其結合到一個臨時對象(rvalue)在find_first的返回時被銷燬並且使match的迭代器失效。

+1

這真的是一個很差的原因。雖然它解決了這種潛在的未定義行爲,但它也會抑制潛在用途,因爲您只需獲取const引用並可能需要在其中進行搜索。 –

+0

使用C++ 11時,在允許傳遞const-ref的同時可以防止右值綁定,但是我懷疑這種方法是由於其廣泛的兼容性而選擇的。它並不完全抑制你提到的情況 - 在一個const引用內部搜索 - 它只是要求調用者用const_iterator模板參數創建一個非const的iterator_range來「證明」迭代對象具有足夠的生命週期。這並不理想,我認爲我更喜歡在腳下拍自己的能力,但至少我明白爲什麼這樣寫。 –

+1

我見過相反的設計決定(接受臨時)咬人幾次,看到[這裏](http://stackoverflow.com/questions/9565375/what-is-prefered-way-of-passing-pointer-引用到現有對象在一個建設)和[這裏](http://stackoverflow.com/questions/11991964/constraints-on-the-lifetime-of-the-argument-to-stdregex-match例如-and-stdregex)。無論你選擇哪種方式,如果他們記錄這些東西,這將是很好的。 –

相關問題