如何用std::invoke_result_t替换非类型模板参数lambda的decltype
如何将decltype获取返回值的写法替换为std::invoke_result_t
待替换的原始写法
你需要替换的代码片段如下:
decltype(f.template operator()<0>())
完整上下文原始代码
template <size_t I, typename Functor> consteval void apply(Functor&& f) { using ResultType = decltype(f.template operator()<0>())>); // 原代码此处多了一个多余的右尖括号 // ... 其余业务逻辑 ... f.template operator()<I>()); // 原代码此处多了一个多余的右括号 } void test() { apply<5>([]<auto I>() { }); }
替换方案
首先需要引入<type_traits>头文件(std::invoke_result_t定义在此头文件中),替换后的正确写法如下:
#include <cstddef> #include <type_traits> template <size_t I, typename Functor> consteval void apply(Functor&& f) { using ResultType = std::invoke_result_t< decltype(&std::remove_cvref_t<Functor>::template operator()<0>), Functor >; // ... 其余业务逻辑 ... f.template operator()<I>(); } void test() { apply<5>([]<auto I>() { }); }
写法说明
- 由于场景中使用的是带非类型模板参数的无参
operator(),无法通过传参让编译器自动推导模板参数,因此需要先显式取实例化后的成员函数指针:通过std::remove_cvref_t<Functor>先去掉转发引用带来的引用、cv限定,拿到仿函数/lambda的裸类型,再取显式指定模板参数为0的operator()地址 - 针对成员函数指针类型,
std::invoke_result_t的第二个参数需要传入成员函数所属对象的类型(对应调用时的this实例),因为该operator()无入参,不需要额外传入参数类型,即可直接得到调用后的返回值类型 - 上述代码已修正原代码中两处多余括号的语法笔误
内容的提问来源于stack exchange,提问作者Violet Giraffe
相关产品推荐
相关产品推荐

