当前位置: 首页 > 知识库问答 >
问题:

如何:捕获输入函数异常的变量包装函数

帅锦
2023-03-14

我正在尝试创建一个可以传递其他函数的函数,它将捕获任何错误,但只返回函数的返回值。以下是我尝试过的:

#include <iostream>
using namespace std;

int fun(int input)
{
    return input;
}

template <typename F, typename...Args>
static auto HandledCall(const F& function, Args...args)
-> decltype(function(...args))
{
    try
    {
        return function(...args);
    }
    catch(...)
    {
        return NULL;
    }
}

int main() {
    std::cout << HandledCall(fun,1) << std::endl; // this should return 1
    std::cout << HandledCall(fun,-1) << std::endl; // this should return 0      
    return 0;
}

我希望意图相对明确;我希望HandledCall能够接收任何类型的函数,并返回其返回值(只要NULL在出错的情况下隐式可转换为该值)。然而,当我试图编译上述代码时,我得到了这些类型的错误;

掠夺。cpp:10:78:错误:应在“…”之前使用主表达式令牌静态自动处理呼叫(const F

很明显,我没有正确地使用可变模板。。。有什么建议吗?

共有3个答案

沈栋
2023-03-14

这是一个基于@Praetorian提供的解决方案的版本,但它也适用于具有space返回类型的函数。其他答案无法处理这种情况的原因是显式实例化了类型为val的对象。

template<typename T> 
T default_value(){return {};}

template<>
void default_value<void>(){}

template<typename F, typename... Args>
typename std::result_of<F(Args...)>::type
  HandledCall(F&& func, Args&&... args)
{
  try {
      return std::forward<F>(func)(std::forward<Args>(args)...);
  } catch(...) {
      return default_value<typename std::result_of<F(Args...)>::type>();
  }
}

之所以这样做,是因为该标准允许在具有void返回类型的函数中显式返回void值。

蒋俊
2023-03-14

像这样的?

#include <iostream>
using namespace std;

int fun(int input)
{
    return input;
}

template <typename T> struct ReturnType;

template<class Ret, class... Args>
struct ReturnType<Ret(Args...)> 
{
   typedef Ret type;
};


template <typename F, typename...Args>
static auto HandledCall(const F& function, Args...args) -> typename ReturnType<F>::type
{
    try
    {
        return function(args...);
    }
    catch(...)
    {
        return typename ReturnType<F>::type{0};
    }
}

int main() {
    std::cout << HandledCall(fun,1) << std::endl; // this should return 1
    std::cout << HandledCall(fun,-1) << std::endl; // this should return 0      
    return 0;
}

使现代化

改进版本的HandledCall(感谢Mankarse):

template <typename F, typename...Args>
static auto HandledCall(const F& function, Args&&...args) -> typename ReturnType<F>::type
{
    try
    {
        return function(std::forward<Args>(args)...);
    }
    catch(...)
    {
        return typename ReturnType<F>::type{0};
    }
}
令狐宜民
2023-03-14

函数调用的返回类型可以使用std::result_of确定。

template<typename F, typename... Args>
typename std::result_of<F(Args...)>::type
    HandledCall(F&& func, Args&&... args)
{
    using result_type = typename std::result_of<F(Args...)>::type;
    try {
        return std::forward<F>(func)(std::forward<Args>(args)...);
    } catch(...) {
        return result_type();
    }
}

现场演示

 类似资料:
  • 问题 你用lambda定义了一个匿名函数,并想在定义时捕获到某些变量的值。 解决方案 先看下下面代码的效果: >>> x = 10 >>> a = lambda y: x + y >>> x = 20 >>> b = lambda y: x + y >>> 现在我问你,a(10)和b(10)返回的结果是什么?如果你认为结果是20和30,那么你就错了: >>> a(10) 30 >>> b(10)

  • 我已经使用C#(库项目)和Aspect(AOP)编写了Azure函数v1用于日志记录。我在catch块中没有得到异常。 捕获异步方法引发的异常 我有上面讨论的相同问题,但Azure函数运行方法是异步任务,其异常处理和异步void相同。不确定哪里有问题?假设这是函数SDK问题。 Azure函数 记录器方面 解决方法:当我从Azure函数中删除异步等待并通过“getWaiter().GetResult

  • 既然闭包可以作为参数,你很可能想知道函数是否也可以呢。确实可以!如果你声明一个接受闭包作为参数的函数,那么任何满足该闭包的 trait 约束的函数都可以作为参数传递。 // 定义一个函数,可以接受一个由 `Fn` 限定的泛型 `F` 参数并调用它。 fn call_me<F: Fn()>(f: F) { f() } // 定义一个满足 `Fn` 限定的装包函数(wrapper functi

  • 我正在使用以下PostgreSQL函数从数据库中的表中删除记录。 上表的主键列(即段表的id列)被另一个表引用为外键,当我执行上述函数从另一个表引用的段表中删除记录时,该函数会按预期引发错误(如下所示)。 现在我从我的Java代码调用这个PostgreSQL函数,它使用Hibernate如下所示, 当我将相同的id传递给上述函数(Integer)(query.list()时。get(0))执行时不

  • 对不起,我不知道这个问题的标题是什么。 我在C中有一个函数,它以λ作为参数。 然后我尝试调用这个函数。 我的问题是,我无法从lambda函数内部访问变量,如果我试图用

  • 问题内容: 我正在尝试从Python内部进行比特币付款。在bash中,我通常会这样做: 因此,例如: 如果成功,我会得到一个交易ID作为输出,但是如果我尝试转账大于我的比特币余额的金额,则会得到以下输出: 现在,在我的Python程序中,我尝试按以下方式进行付款: 如果有足够的余额,则可以正常工作,但是如果没有足够的余额,则会输出以下内容: 它不包括我在命令行中得到的错误。所以我的问题是;如何从P