自1.55

时间:2017-08-07 14:45:14

标签: c++ boost

我正在尝试编译针对Boost 1.55针对较新的Boost 1.63编写的a project,我遇到了与bind / function相关的一个非常奇怪的错误。这是完整,简化的测试用例:

#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&’

如果我尝试使用Boost 1.55的另一台机器,它编译得很好。 (当指向Boost 1.55的构建时,该项目也在同一台机器上编译好了,所以问题似乎不是编译器。)所以,显然Boost中的某些东西已经发生了变化,导致其失败。

我没有写这段代码,也不是我非常熟悉boost::functionboost::bind的胆量。如果有人能向我解释为什么这会破坏新的Boost,或者a)如何修复它,或者b)为什么上面的代码被破坏了,我们将非常感激!

1 个答案:

答案 0 :(得分:7)

问题是boost::function在匹配函数签名方面变得更加严格(我认为更接近匹配std::function的行为)。您的函数被声明为boost::function3< void, Arg1, Arg2, Arg3 >,但是,您绑定到它的函数需要int const&int&

有几种方法可以解决这个问题。你可以:

  1. foo<int, int>中的bar的实例更改为foo<int const&, int&>
  2. function_t的声明更改为boost::function3<void, Arg1, Arg2 const&, Arg3&>
  3. 更改bar::func的签名以按值接受其参数。