2017-08-07 4 views
5

ので、私は新しいブースト1.63に対してブースト1.55に対して書かれたa projectをコンパイルしようとしていた、と私はbind/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. 変更barfoo<int, int>のinstantionはfoo<int const&, int&>されるように。
  2. function_tの宣言をboost::function3<void, Arg1, Arg2 const&, Arg3&>に変更します。
  3. bar::funcのシグニチャを、その引数を値で受け入れるように変更します。
+0

ありがとうございました。面倒なパラメータは出力パラメータなので不可能ですがAFAICT a)このパターンを使った実際のコードは最終的にはストアド関数を呼び出すための有効な参照パラメータを生成できません。 b)実際のタイプはとにかく参照コンテナなので、DTRTもvalue/copyで渡されます。 AFAICT(3)は、実際には実際のコードの正しい修正です。 (レコードの注意: 'const&'引数は依然として適合でき、参照パラメータだけを変更する必要があります。) – Matthew