获取模板类中模板方法的返回类型——编译报错求助
获取模板类中模板方法的返回类型——编译报错求助
兄弟,我来帮你分析下这个编译错误的原因,以及怎么解决:
问题根源
你报错的核心原因是:bar<T>::func是一个模板成员函数,直接写&bar<T>::func的时候,编译器根本不知道要实例化哪个版本的func(毕竟它是可变参数模板),std::invoke_result_t无法推导这个不明确的函数指针类型,所以才会抛出“Template argument for template type parameter must be a type”的错误。
解决方案一:用decltype直接推导(最简洁)
这是最直观的方式,我们可以通过模拟调用func的表达式,让decltype直接推导返回类型,不需要处理复杂的函数指针:
#include <iostream> #include <type_traits> #include <utility> // 用于std::declval template <typename T, typename... Args> struct foo {}; template <typename T> struct bar { template <typename... Args> auto func(Args... args) { // 这里注意:你原来的foo(*this, args...)会实例化foo<bar<T>, Args...> // 如果你的目标是foo<T, Args...>,要改成下面这样 return foo<T, Args...>(args...); } }; // 核心修改:用decltype结合std::declval模拟调用 template <typename T, typename... Args> using bar_func_return_type = decltype(std::declval<bar<T>>().func(std::declval<Args>()...)); int main() { // 注意:你原来的floar是拼写错误,要改成float if constexpr (std::is_same_v<bar_func_return_type<int, float, double>, foo<int, float, double>>) { std::cout << "OK"; } else { std::cout << "FAIL"; } return 0; }
解释一下:
std::declval<bar<T>>():用来生成一个bar<T>类型的临时右值,不需要实际构造对象,专门用于类型推导std::declval<Args>()...:同理,生成Args类型的临时右值作为func的参数decltype(...):直接获取这个调用表达式的返回类型
解决方案二:明确指定模板函数指针(如果你一定要用std::invoke_result_t)
如果坚持要用std::invoke_result_t,你需要明确指定func的模板参数,同时告诉编译器func是模板成员函数,还要补上成员函数调用需要的对象类型:
template <typename T, typename... Args> using bar_func_return_type = std::invoke_result_t< decltype(&bar<T>::template func<Args...>), // 明确指定func的模板参数,用template关键字标记 bar<T>&, // 成员函数调用需要的对象类型(非const成员函数需要左值引用) Args... // 函数参数类型 >;
额外的小错误提醒
你代码里还有两个容易忽略的小问题:
floar是拼写错误,应该是float- 原来的
func里return foo(*this, args...);会实例化foo<bar<T>, Args...>,但你后面的is_same_v里写的是foo<int, float, double>,这两者类型不匹配,所以要把func里的返回语句改成return foo<T, Args...>(args...);(或者根据你的实际需求调整foo的模板参数)
备注:内容来源于stack exchange,提问作者mouse_00
相关产品推荐
相关产品推荐

