2017-08-07 78 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

相关问题