GCC12依赖类型别名仅允许类类型,其他编译器支持基础类型的原因
GCC 12.1+编译模板别名代码的报错问题
现象描述
某段模板别名代码在GCC 11、Clang、MSVC中均可正常编译,但从GCC 12.1版本开始会触发编译错误:
using Y = typename Derived::template X<1>; // 报错行
对应的错误提示为:
error: 'class Derived
::X<1>' resolves to 'Base ::X<1>' {aka 'double'}, which is not a class type
实际测试发现,当模板别名X<1>解析为类类型时代码可正常运行,但解析为算术类型(如double)时就会报错。而单独写using Y = double;是完全合法的,且只要Base、Derived或X任意一个是非模板结构,代码也能正常编译。
最小复现代码
#include <iostream> template <typename T> struct Base { template <int I> using X = T; }; template <typename T> struct Derived : public Base<T> { using Y = typename Derived::template X<1>; }; struct O {}; int main() { std::cout << typeid(Derived<double>::Y).name() << std::endl; // 触发报错 std::cout << typeid(Derived<O>::Y).name() << std::endl; // 正常运行 }
核心疑问
为什么在这种模板嵌套的依赖类型场景下,X<1>必须解析为类类型才能合法创建别名?为何该问题仅出现在GCC 12.1及以上版本?(已查阅GCC 12变更列表,未找到相关说明,且问题在C++11/14/17/0x标准下均存在)
内容的提问来源于stack exchange,提问作者gchen
相关产品推荐
相关产品推荐

