VC2019(C++20)环境下编译器无法推导模板参数_t1与_t2的问题求解
解决模板参数推导失败的问题
首先得明确问题根源:你传递给_ChTest的是聚合初始化的braced-init-list(也就是{._x = i, ._y = j}),这种列表属于C++里的「非推导上下文」——编译器没办法从这个列表反向推导出模板参数_t1和_t2,因为它不知道这个列表对应哪个具体的str特化版本。
下面给你几个实用的解决思路,按优雅程度排序:
思路1:给str添加类模板推导指引(C++17+)
这是最推荐的方案,让编译器能从初始化表达式自动推导str的模板参数。你只需要在str结构体定义后加一行推导指引:
#include <tuple> template <typename... arg> requires(sizeof...(arg) == 2) struct str { std::tuple_element<0, std::tuple<arg...>>::type _x; std::tuple_element<1, std::tuple<arg...>>::type _y; }; // 添加类模板推导指引,适配聚合初始化的类型推导 template <typename T1, typename T2> str(T1, T2) -> str<T1, T2>; template <typename _t1, typename _t2> void _ChTest(str<_t1, _t2> s) { // ... } int main() { int i = 1, j = 2; // 现在编译器能通过推导指引,自动推导出str<int, int> _ChTest({._x = i, ._y = j}); return 0; }
思路2:显式指定模板参数
这是最直接但不够优雅的方案,调用函数时手动告诉编译器模板参数的类型:
int main() { int i = 1, j = 2; // 显式指定_t1=int,_t2=int _ChTest<int, int>({._x = i, ._y = j}); return 0; }
思路3:先构造str对象再传递
先通过CTAD(类模板实参推导)构造一个str实例,再把它传给函数——这样编译器能先推导出str的类型,再匹配函数的模板参数:
int main() { int i = 1, j = 2; str s{._x = i, ._y = j}; // CTAD自动推导出str<int, int> _ChTest(s); return 0; }
思路4:修改函数参数为auto(C++14+)
如果你的函数不需要单独处理_t1和_t2,可以直接用auto作为参数类型,让编译器自动推导整个str的类型:
// 替代原来的模板函数 void _ChTest(auto s) { // 如果需要获取_t1和_t2的类型,可以用decltype: using _t1 = decltype(s._x); using _t2 = decltype(s._y); // ... } int main() { int i = 1, j = 2; _ChTest({._x = i, ._y = j}); return 0; }
内容的提问来源于stack exchange,提问作者VeNToR
相关产品推荐
相关产品推荐

