2017-08-07 77 views
5

奇怪的行爲變化我試圖編譯a project是針對Boost 1.55針對較新的Boost 1.63編寫的,而且我遇到了與bind/function相關的非常奇怪的錯誤。下面是完整的,簡單的測試用例:boost :: bind/boost :: function自從1.55

#include <boost/bind.hpp> 
#include <boost/function.hpp> 

template < typename Arg1 = int, typename Arg2 = int, typename Arg3 = int > 
class foo 
{ 
public: 
    using function_t = boost::function3< void, Arg1, Arg2, Arg3 >; 

    void set_function(function_t f) 
    { 
    func_ = f; 
    } 

private: 
    function_t func_; 
}; 

class bar 
{ 
public: 
    bar() 
    { 
    foo_.set_function(boost::bind(&bar::func, this, _1, _2)); 
    } 

private: 
    void func(int const&, int&) {} 

    foo< int, int > foo_; 
}; 

int main() 
{ 
    bar x; 
    return 0; 
} 

...和錯誤的一些選擇片段我越來越:

/usr/include/boost/bind/bind.hpp:398:35: error: no match for call to ‘(boost::_mfi::mf2<void, bar, const int&, int&>) (bar*&, int, int)’ 
/usr/include/boost/bind/mem_fn_template.hpp:278:7: note: candidate: R boost::_mfi::mf2<R, T, A1, A2>::operator()(T*, A1, A2) const [with R = void; T = bar; A1 = const int&; A2 = int&] <near match> 
/usr/include/boost/bind/mem_fn_template.hpp:278:7: note: conversion of argument 3 would be ill-formed: 
/usr/include/boost/bind/bind.hpp:398:35: error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’ 
/usr/include/boost/bind/mem_fn_template.hpp:283:25: note: candidate: template<class U> R boost::_mfi::mf2<R, T, A1, A2>::operator()(U&, A1, A2) const [with U = U; R = void; T = bar; A1 = const int&; A2 = int&] 
/usr/include/boost/bind/mem_fn_template.hpp:283:25: note: template argument deduction/substitution failed: 
/usr/include/boost/bind/bind.hpp:398:35: note: cannot convert ‘(& a)->boost::_bi::rrlist3<int, int, int>::operator[](boost::_bi::storage3<boost::_bi::value<bar*>, boost::arg<1>, boost::arg<2> >::a3_)’ (type ‘int’) to type ‘int&’ 
/usr/include/boost/bind/mem_fn_template.hpp:291:25: note: candidate: template<class U> R boost::_mfi::mf2<R, T, A1, A2>::operator()(const U&, A1, A2) const [with U = U; R = void; T = bar; A1 = const int&; A2 = int&] 
/usr/include/boost/bind/mem_fn_template.hpp:291:25: note: template argument deduction/substitution failed: 
/usr/include/boost/bind/bind.hpp:398:35: note: cannot convert ‘(& a)->boost::_bi::rrlist3<int, int, int>::operator[](boost::_bi::storage3<boost::_bi::value<bar*>, boost::arg<1>, boost::arg<2> >::a3_)’ (type ‘int’) to type ‘int&’ 
/usr/include/boost/bind/mem_fn_template.hpp:299:7: note: candidate: R boost::_mfi::mf2<R, T, A1, A2>::operator()(T&, A1, A2) const [with R = void; T = bar; A1 = const int&; A2 = int&] 
/usr/include/boost/bind/mem_fn_template.hpp:299:7: note: no known conversion for argument 1 from ‘bar*’ to ‘bar&’ 

如果我嘗試具有升壓1.55另一臺機器上,它編譯正好。 (當指向構建Boost 1.55時,該項目在同一臺機器上編譯也沒問題,所以問題看起來並不是編譯器。)所以,顯然Boost中的某些內容已經改變,導致它失敗。

我沒有寫這段代碼,我不是很熟悉boost::functionboost::bind的膽量。如果有人可以向我解釋爲什麼這會破壞新的Boost,或者a)如何修復它,或者b)爲什麼上面的代碼被破壞,這將是非常感謝!

回答

6

問題是boost::function在匹配函數簽名(我認爲更接近地匹配std::function的行爲)方面變得更加嚴格。您的函數聲明爲boost::function3< void, Arg1, Arg2, Arg3 >,但是,您綁定的函數需要int const&int&

有幾種方法可以解決這個問題。你可以:

  1. 變化foo<int, int>bar的instantion爲foo<int const&, int&>
  2. function_t的聲明更改爲boost::function3<void, Arg1, Arg2 const&, Arg3&>
  3. bar::func的簽名更改爲通過值接受其參數。
+0

謝謝。我會說(3)是不可能的,因爲麻煩的參數是輸出參數,但深入挖掘,AFAICT a)使用此模式的實際代碼不可能產生最終調用存儲函數的有效參考參數, b)實際的類型無論如何都是一個參考容器,DTRT甚至會通過值/副本傳遞。所以AFAICT,(3)實際上是真正的代碼的正確解決方案。 (注意記錄:'const&'參數仍然可以調整;只有參考參數需要改變。) – Matthew

相關問題