C++聚合体圆括号初始化的模板实参推导,MSVC报错是否为BUG?
该现象属于MSVC的编译器BUG,本质是其对C++20标准中聚合类圆括号初始化对应的类模板实参推导(CTAD)规则支持不完善。
规则背景说明
下述测试代码是聚合类模板CTAD的典型场景:
template<typename T> struct A{ T x; }; int main() { static_assert( A{1}.x == 1 ); //#1: GCC和MSVC均编译通过 static_assert( A(1).x == 1 ); //#2: 仅GCC编译通过 }
两种初始化形式的标准支持情况如下:
- 对于
A{1}的花括号初始化:C++17版本正式引入CTAD特性时,就已经明确支持聚合类模板通过花括号列表的实参推导模板参数,因此GCC、MSVC都能正常处理这段代码,符合标准要求。 - 对于
A(1)的圆括号初始化:C17标准中不允许用圆括号初始化聚合类型,因此对应的CTAD规则也不支持这种场景。直到C20通过提案P0960R3正式放开限制,允许用圆括号初始化聚合,同时更新CTAD规则适配这种场景,要求编译器可以根据圆括号内的实参推导聚合类模板的参数。
编译器实现差异说明
GCC很早就完整实现了C20的这一规则,因此两种写法都能正常编译。而MSVC至今仅完成了花括号场景下的聚合类CTAD实现,尚未适配圆括号初始化的CTAD规则,抛出的cannot deduce template arguments for 'A'系列错误本质是其没有为圆括号初始化的聚合类触发CTAD推导,转而尝试匹配不存在的构造函数,该行为不符合C20标准的要求,属于编译器缺陷。
目前MSVC官方反馈渠道中已有开发者提交过相关问题,该BUG仍处于待修复状态。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

