【问题标题】:How to recognize or avoid empty boost::function as std::function如何识别或避免空的 boost::function 为 std::function
【发布时间】:2019-01-24 10:48:58
【问题描述】:

我目前正在编写一个代码,主要使用 boost,但越来越多地转向 C++11,它是标准库。

我在将一个空的 boost::function 作为回调传递给 std::function 时发生了崩溃:

#include <boost/function.hpp>
#include <functional>
#include <iostream>

int main()
{
   boost::function <void(void)> boost_f;
   std::function <void(void)> std_f;
   std::cout << "used " << (std_f!=nullptr) << " " << (!boost_f.empty()) << "\n";

   boost_f = boost::function<void(void)>();
   std_f = boost_f;
   std::cout << "used " << (std_f!=nullptr) << " " << (!boost_f.empty()) << "\n";

   if( std_f )
      std_f();
}

std::function 声称它有一个有效的目标,但是空的 boost::function 抛出一个异常:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_function_call> >'
  what():  call to empty boost::function

使用 gcc-6.3.1 和 clang-4.0 测试。

我怎样才能避免这个问题?是否可以解决此问题,以便分配给 std::function 的空 boost::function 给出一个空的 std::function?或者我可以明确检查 std::function 是否有分配给它的空 boost::function?

只避免异常不是预期的解决方案,因为函数的行为应该取决于回调集与否(而且它通常没有设置,因此也应该避免捕获异常)。

【问题讨论】:

  • 我认为您不能在分配或初始化时进行检查,因为在这方面没有挂钩或自定义点来改变 std::functionboost::function 的默认行为。但是,辅助函数boostFctOrEmpty(boost::function&lt;...&gt;&amp;) 怎么样?如果它是非空的,这可能会返回函数对象,否则返回一个空的std::function 对象。
  • 调用方需要这些辅助函数吗?在实际代码中,回调是通过函数设置的,我想避免调整调用者。一种选择是用 std::function 和 boost:.function 重载回调 setter 接口,直到所有调用者都使用 std::function...
  • 您可以使用 try-catch 对来捕获异常并进行处理。
  • @eprom 我也考虑过捕获,但这会产生太多过时的异常(请参阅我的问题)

标签: c++11 boost


【解决方案1】:

这个怎么样:

    if(std_f)
    {
        if( std_f.target_type()==typeid(boost::function<void(void)>))
        {
            auto boostF=std_f.target<boost::function<void(void)>>();
            if(boostF&&*boostF)
                std_f();
            else
            {
                std::cout<<"empty boost function"<<std::endl;
            }
        }
        else
            std_f();
    }

【讨论】:

  • 谢谢,这确实有效,并且可以在存储回调的函数中有效地实现。
  • 不客气!顺便说一句,如果你不使用无法修改的第三方库,最好只使用 std::function 和 boost::function 之一。像你这样混用就相当于把一个callable对象包裹了两层,所以会出现这样的问题。
猜你喜欢
  • 2012-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
相关资源
最近更新 更多