jjzjj

c++ - 自 1.55 以来 boost::bind/boost::function 的奇怪行为变化

coder 2024-02-03 原文

我正在尝试编译 a project这是针对 Boost 1.55 和较新的 Boost 1.63 编写的,我遇到了一个与 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) 为什么上面的代码被破坏,我将不胜感激!

最佳答案

问题是 boost::function在匹配函数签名方面变得更加严格(我认为更接近地匹配 std::function 的行为)。您的函数声明为 boost::function3< void, Arg1, Arg2, Arg3 > ,但是,您绑定(bind)到它的函数需要 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 的签名按值(value)接受其论点。

关于c++ - 自 1.55 以来 boost::bind/boost::function 的奇怪行为变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45549724/

有关c++ - 自 1.55 以来 boost::bind/boost::function 的奇怪行为变化的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  3. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  4. ruby-on-rails - 启用 Rack::Deflater 时 ETag 发生变化 - 2

    在启用Rack::Deflater来gzip我的响应主体时偶然发现了一些奇怪的东西。也许我遗漏了一些东西,但启用此功能后,响应被压缩,但是资源的ETag在每个请求上都会发生变化。这会强制应用程序每次都响应,而不是发送304。这在没有启用Rack::Deflater的情况下有效,我已经验证页面源没有改变。我正在运行一个使用thin作为Web服务器的Rails应用程序。Gemfile.lockhttps://gist.github.com/2510816有没有什么方法可以让我从Rack中间件获得更多的输出,这样我就可以看到发生了什么?提前致谢。 最佳答案

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  7. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

  10. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

随机推荐