用户定义的lambda演绎指南

Inl*_*ine 3 c++ template-argument-deduction c++17

今天我在努力学习C++模板.这是我在JNI代码中方便异常处理的简单代码.

template<typename T>
std::optional<T> handleNativeCrash(JNIEnv *env, std::function<T(void)> f) {
    try {
        return std::optional<T>(f());
    }
    catch (const std::exception &e) {
        jniThrowException(env, e.what());
        return {};
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用它而没有指定时T,Clang大致失败了这个错误

no matching function for call to 'handleNativeCrash'
      return my_namespace::handleNativeCrash(env, [&]{
             ^~~~~~~~~~~~~~~~~~~~~
  /......../jni.cpp:116:39)'
      std::optional<T> handleNativeCrash(JNIEnv *env, std::function<T(void)> f) {
                       ^
  1 error generated.
Run Code Online (Sandbox Code Playgroud)

我想T从lambda返回类型自动推断.我试着编写演绎指南,但似乎我无法为全局函数编写它.我试图创建只包含此函数的简单模板结构,但我也失败了.看来我并不真正理解C++模板元编程.

我的第一次尝试是这样的,但Clang只是抱怨非法语法并打印它的回溯.我会尽快报告错误,但我需要先完成这项工作.

template<typename T>
handleNativeCrash(JNIEnv *env, std::function<T(void)> f) -> handleNativeCrash<decltype(f())>;
Run Code Online (Sandbox Code Playgroud)

我怎样才能实现目标?

YSC*_*YSC 8

你不能使用模板推导,它不够智能,只适用于匹配.

但你可以手动推断它:

template<class Callable>
auto handleNativeCrash(JNIEnv *env, Callable f)
-> std::optional<decltype(f())>
{
    try {
        return f();
    }
    catch (const std::exception &e) {
        jniThrowException(env, e.what());
        return {};
    }
}
Run Code Online (Sandbox Code Playgroud)

简化的现场演示

  • @dedup这是一个选项,但基本上我不想隐藏函数impl中的返回类型(一个noptional). (2认同)