【问题标题】:How to write a generalized function wrapper using variadic templates如何使用可变参数模板编写通用函数包装器
【发布时间】:2019-10-27 18:14:13
【问题描述】:

我刚刚开始沉迷于模板的高级使用。我正在尝试为函数编写一个通用包装器,以包装可能导致异常的函数。如果没有发生异常,包装函数应该将实际返回值写入某个引用,然后返回true。如果发生异常,它只返回false

代码

#include <string>
#include <iostream>
#include <functional>
#include <exception>
#include <iomanip>

template<typename TReturn, typename ... TArgs>
bool Try(std::function<TReturn(TArgs...)> &function, typename std::function<TReturn(TArgs...)>::result_type& res, TArgs&...args) {
    try {
        res = function(std::forward<TArgs>(args)...);

        return true;
    }
    catch (...) {
        return false;
    }
}

std::string foo(int val) {
    if (val == 0) {
        throw std::exception();
    }

    return "result";
}

int main() {
    std::string res = "noResult";

    //Should be "false=>noResult"
    std::cout << std::boolalpha << Try(foo, res, 0) << "=>" << res;

    //Should be "true=>result"
    std::cout << std::boolalpha << Try(foo, res, 1) << "=>" << res;
}

期望

我期望像bool Try(std::function&lt;std::string(int)&gt;&amp; function, std::string&amp; res, int&amp;arg);这样的模板实例化

相反,它甚至不编译:

错误:

没有函数模板“Try”的实例与参数列表匹配

'bool Try(std::function<_ret>,std::function<_ret>::result_type &,TArgs &...)': 无法推断'std::function<_ret>' 的模板参数来自'std::string (int)'

我想我打电话给Try 的方式也可能有缺陷。


我找到了this simliar question,但我无法让它与返回类型一起工作。

是的,对于返回 void 的函数,需要有一个特殊的重载。


我错过了什么,怎么能做到这一点?提前致谢!

【问题讨论】:

  • 您是否尝试过调用 Try like this: Try(foo, res, 0) ?
  • 对于一个你的Targs ... 有点偏离,你可能打算使用'&&'而不是'&'

标签: c++ variadic-templates


【解决方案1】:

为什么这么多std::function

template<typename TReturn, typename ... TArgs>
bool Try(TReturn (&function)(TArgs...), TReturn& res, TArgs...args) {
    try {
        res = function(std::forward<TArgs>(args)...);

        return true;
    }
    catch (...) {
        return false;
    }
}

您也不能将0 之类的参数作为参考TArgs&amp;... 传递。照原样通过它们。

【讨论】:

  • 为什么不接受任何可调用的?您将很快在此处遇到从函数签名和args 推断不匹配的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-08
  • 2023-03-15
  • 2016-12-11
  • 1970-01-01
  • 2020-07-31
  • 2015-05-06
  • 2019-12-20
相关资源
最近更新 更多