为何构造函数声明后不能加<T>?C++17与C++20编译差异解析
C17与C20中构造函数显式指定模板参数的编译差异原因
问题现象
在C++17环境下,以下代码可以正常编译:
template <class T> struct Foo { Foo<T>() = default; }; int main() { Foo<int> foo; return 0; }
但在C++20环境下,编译器会抛出如下错误:
main.cpp:3:16: error: expected unqualified-id before ‘)’ token 3 | Foo<T>() = default; | ^
移除构造函数后的<T>,代码即可在C++20中正常编译:
template <class T> struct Foo { Foo() = default; }; int main() { Foo<int> foo; return 0; }
差异原因
C++20对类模板中构造函数的名称解析规则做了严格修正:
- 在C++17及更早版本中,编译器会宽松地将
Foo<T>()解析为类模板Foo的构造函数,把带模板参数的类名视为构造函数的合法名称。 - 而C++20严格遵循标准定义:类模板的构造函数名称必须与类名完全一致,不能附加模板参数列表。此时
Foo<T>会被编译器解析为一个类型名(即实例化后的Foo<T>类类型),而非构造函数的名称,用类型名来声明函数会直接触发语法错误,因此编译失败。
本质上,C20是修正了之前编译器的宽松行为,严格对齐了C标准中关于构造函数命名的规定——构造函数的名字就是类的名字,不存在带模板参数的构造函数写法。
内容的提问来源于stack exchange,提问作者Hunter
相关产品推荐
相关产品推荐

