2011-12-20 75 views
7

不能爲我的生命明白爲什麼失敗:爲什麼boost :: equals要求範圍是可複製的?

#include <vector> 

#include "boost/algorithm/string/predicate.hpp" 

struct Test 
: 
    public std::vector<int> 
{ 
    Test() { } 
    Test(const Test&) { assert(false); } 
}; 

int main() 
{ 
    Test a; 
    Test b; 
    boost::algorithm::equals(a, b); 

    return 0; 
} 

輸出:

$ g++ boostEqualsCopyDemo.cpp -I /usr/include/boost-1_47 
$ a.out 
a.out: boostEqualsCopyDemo.cpp:10: Test::Test(const Test&): Assertion `false' failed. 
Aborted (core dumped) 

我試着挖過升壓代碼,但它使我目瞪口呆。這似乎是荒謬的;如此浪費和不必要。這是怎麼回事?

回答

10

Boost正試圖爲您傳入的容器製造一組範圍,最後調用range_detail::is_char_ptr(),這是一組函數模板的名稱,它使用模板參數推導來確定該參數是否爲char某種形式的指針(或者你可能會猜到這個名字)。

不幸的是,匹配非char指針參數時,返回0的'catch-all'函數模板將按值取其參數。

我認爲這可以通過改變參數取代const&來解決。看文件boost/range/as_literal.hpp爲:

template< class T > 
    inline long is_char_ptr(T /* r */) 
    { 
     return 0L; 
    } 

並將其更改爲:

template< class T > 
    inline long is_char_ptr(T const& /* r */) // <-- add const& 
    { 
     return 0L; 
    } 

我絕不是在複雜的模板庫執行情況的專家(我用他們,我不不要寫'時間),所以我不會聲稱這種改變不會引起其他一些討厭的副作用。

+4

有關此問題的錯誤報告,請參閱https://svn.boost.org/trac/boost/ticket/6149。 – 2011-12-20 09:29:35

+1

此修復程序現在位於助力幹線中,應該是1.50版本的一部分:https://svn.boost.org/trac/boost/ticket/6149#comment:2 – 2012-04-16 05:37:43