C++20聚合类型自动模板推导编译兼容性问题咨询
C++20相关语法变更解释
你给出的测试代码如下:
template <class T> struct Foo { T value; }; int main() { return Foo<int>(0).value; // 以下代码在GCC中同样可以正常运行 // return Foo(0).value; }
1. 显式指定模板参数时的编译差异原因
C17及更早标准中,聚合类型只能通过花括号{}完成初始化,使用圆括号()会被编译器判定为尝试调用类的构造函数。你定义的Foo是无自定义构造函数的聚合类型,因此C17模式下Foo<int>(0)会因为找不到匹配的构造函数报错。
C20通过了P0960R3提案,正式允许聚合类型使用圆括号进行初始化,初始化规则与花括号基本一致(仅排除了花括号独有的初始化列表构造函数匹配、窄化转换检查等逻辑),因此C20模式下Foo<int>(0)属于合法的聚合初始化写法。
2. 省略模板参数写法的支持原因
GCC支持Foo(0)无模板参数写法,是C++20的另一项变更:P1816R0提案,该提案允许对聚合类模板自动进行类模板实参推导(CTAD),不需要用户额外编写推导指引。编译器可以根据你传入圆括号的参数0的类型int,自动推导出模板参数T为int,完成Foo的实例化。
编译器兼容性说明
目前GCC 10+、最新版MSVC已经完整实现了上述两个C20提案,因此可以正常编译两种写法。Clang 13/14对这两个特性的实现存在缺失,尤其是聚合类模板结合圆括号初始化的场景支持不完善,因此即便开启C20模式也无法编译通过,属于编译器实现进度的差异,不符合标准要求的行为。
内容的提问来源于stack exchange,提问作者Stéphane Janel
相关产品推荐
相关产品推荐

