C++20中能否对偏特化类模板的别名模板使用类模板实参推导?
C++20中偏特化类模板的别名模板能否使用类模板实参推导?
答案是不能直接使用,C++20标准并未支持对别名模板自动应用类模板实参推导(CTAD),哪怕该别名指向的是带有构造函数的类模板偏特化。
问题分析
你给出的代码中,foo_int是一个别名模板,本质只是foo<T, int>的类型别名,并非独立的类模板。当你尝试写foo_int(1.0)时,编译器不会自动穿透别名模板,去匹配foo<T, int>偏特化中的构造函数来推导T的类型——因为CTAD的规则只针对类模板本身,别名模板不会触发默认的推导逻辑。
解决办法
如果你想避免显式指定模板参数,有两种可行方案:
1. 为别名模板添加自定义推导指引
显式告诉编译器如何从构造函数参数推导别名模板的模板参数:
template <typename T, typename U> struct foo; template <typename T> struct foo<T, int> { const T t; foo(T t) : t(t) {} }; template <typename T> using foo_int = foo<T, int>; // 为foo_int添加推导指引 template <typename T> foo_int(T) -> foo_int<T>; int main() { auto bar = foo_int(1.0); // 编译通过,T被推导为double }
2. 使用工厂函数封装推导逻辑
如果不想用推导指引,可以写一个简单的工厂函数来隐式推导模板参数:
template <typename T, typename U> struct foo; template <typename T> struct foo<T, int> { const T t; foo(T t) : t(t) {} }; template <typename T> using foo_int = foo<T, int>; // 工厂函数 template <typename T> foo_int<T> make_foo_int(T t) { return foo_int<T>(t); } int main() { auto bar = make_foo_int(1.0); // 编译通过,T被推导为double }
补充说明
将foo_int改为派生类能正常编译,是因为派生类本身是独立的类模板,会触发默认的CTAD逻辑;而显式指定foo_int<double>本质是跳过了推导步骤,直接实例化模板。
内容的提问来源于stack exchange,提问作者Kevlar
相关产品推荐
相关产品推荐

