C++20代码可在Clang编译通过,GCC下编译失败原因咨询
GCC C++20下模板类构造函数委托编译失败的原因
问题代码
#include <string> template <typename Tag> struct StrongSymbol { explicit StrongSymbol<Tag>(std::string name) : m_name(std::move(name)) {} StrongSymbol<Tag>() : StrongSymbol<Tag>("") {} std::string m_name; };
问题现象
上述代码可在Clang中正常编译,但在GCC启用-std=c++20编译选项时会报错:
error: expected unqualified-id before ')' token
6 | StrongSymbol() : StrongSymbol ("") {}
| ^
原因分析
这是GCC在C20模式下的解析逻辑问题。C20引入了显式构造函数模板实参推导(CTAD),GCC在处理模板类的无参构造函数定义时,错误地将StrongSymbol<Tag>()解析成了一个函数声明(试图触发CTAD相关的语法解析),而非预期的构造函数委托调用。
在类的内部作用域中,StrongSymbol是注入的类名,本身就指代当前特化StrongSymbol<Tag>,因此委托构造时不需要显式指定模板参数。
修复方式
修改无参构造函数的写法,去掉委托调用中的模板参数即可正常编译:
StrongSymbol() : StrongSymbol("") {}
或者保留模板参数但改用列表初始化形式,规避GCC的解析歧义:
StrongSymbol<Tag>() : StrongSymbol<Tag>{}("") {}
是否属于GCC的bug
是的,这属于GCC的解析bug。根据C标准,在类成员定义的语境下,StrongSymbol<Tag>()应当被正确解析为当前类特化的构造函数调用,用于委托构造。Clang的处理符合标准规范,而GCC在C20模式下的解析逻辑出现了偏差。
内容的提问来源于stack exchange,提问作者Ofek Shilon
相关产品推荐
相关产品推荐

