2009-07-08 114 views
2

我怎樣才能得到這個編譯?錯誤是當我開始使用boost :: ref()。我認爲boost :: ref用於傳遞對C++算法類的引用?正確使用Boost :: ref ..?

list<Object> lst; 
    lst.push_back(Object(1,2.0f)); 
    lst.push_back(Object(3,4.3f)); 

    struct between_1_and_10 
    { 
    int d; 
    void operator() (Object& value) 
    { 
     value.a += 5; value.b -= 3.3f; 
     cout << d << endl; 
     d += value.a; 
    } 
    }; 

    between_1_and_10 val; 
    val.d = 4; 
    for_each(lst.begin(), lst.end(), boost::ref(val)); // Problem is here 
    printf("rg"); 

編輯這裏的編譯器錯誤的人建議:

1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\algorithm(29) : error C2064: term does not evaluate to a function taking 1 arguments 
1>  c:\users\swangrun\desktop\minescout work\feat-000-gettargetimages\minescouttest\maintest.cpp(102) : see reference to function template instantiation '_Fn1 std::for_each<std::list<_Ty>::_Iterator<_Secure_validation>,boost::reference_wrapper<T>>(_InIt,_InIt,_Fn1)' being compiled 
1>  with 
1>  [ 
1>   _Fn1=boost::reference_wrapper<main::between_1_and_10>, 
1>   _Ty=Object, 
1>   _Secure_validation=true, 
1>   T=main::between_1_and_10, 
1>   _InIt=std::list<Object>::_Iterator<true> 
1>  ] 
+0

好的。它應該在for_each()行上。但問題是什麼。您必須向我們提供錯誤或足夠的代碼,以便我們重現錯誤。 – 2009-07-08 01:43:45

+0

問題是它不能編譯。我已經接受了答案,謝謝你的參與! – sivabudh 2009-07-08 01:50:38

回答

7

這是你真正想要的:

for_each(lst.begin(), lst.end(), boost::bind<void>(boost::ref(val),_1 )); 

編輯:於OP要求一些解釋。回想一下,for_each()接受一個函數,但你只是傳遞一個對你的結構的引用(是的,結構有它的operator()重載,但你沒有通過它)。 bind()基本上「暴露」你的結構中的函數。

編輯2:「_1」的解釋可以在下面的註釋中找到。

-1

嘗試沒有了boost :: REF。

12

boost::reference_wrapper(這是什麼boost::ref返回)不會超載operator()。您可以使用它與boost::bind,它有特殊對待它(不使用ref將使bind複製提供的功能對象)。

但是for_each返回它調用的東西的函數對象。因此,只要做到這一點

between_1_and_10 val; 
val.d = 4; 
val = for_each(lst.begin(), lst.end(), val); 
printf("rg"); 

它將呼籲複製val的東西,並返回函數對象,因爲它是最後調用之後。


只是告訴你,你可能會使用boost::ref,因爲你似乎濫用它。想象一下,一個模板,通過價值需要它的參數,並調用另一個函數:

void g(int &i) { i++; } 

template<typename T> 
void run_g(T t) { g(t); } 

如果你現在想用一個變量來調用它,它會複製它。通常,這是一個合理的決定,例如,如果要將數據作爲開始參數傳遞給線程,可以將其從本地函數複製到線程對象中。但有時候,你可能不想複製它,而是真的傳遞一個參考。這是boost::reference_wrapper有幫助的地方。實際上下面做什麼我們期待,並輸出1

int main() { 
    int n = 0; 
    run_g(boost::ref(n)); 
    std::cout << n << std::endl; 
} 

綁定參數,副本是一個很好的默認。它也很容易使數組和函數衰減到指針(通過引用接受將使得T可能是一個數組/函數類型,並會導致一些討厭的問題)。