带concepts与实际类型的模板特化存在歧义:哪个编译器正确?
C++模板特化与Concept约束的歧义问题分析
问题代码
#include<concepts> template<typename> void foo() { } template<std::integral> void foo() { } template<> void foo<bool>() { } int main() { foo<bool>(); }
编译表现
这段代码可在新版Clang和MSVC中正常编译,但在GCC中编译失败,报错信息如下:
error: ambiguous template specialization 'foo<bool>' for 'void foo()' 9 | void foo<bool>() { } | ^~~~~~~~~ note: candidates are: 'template<class> void foo()' 3 | void foo() { } | ^~~ note: 'template<class> requires integral< <template-parameter-1-1> > void foo()' 6 | void foo() { } | ^~~
编译器正确性判断
你的结论是对的,GCC的处理不符合C++标准,Clang和MSVC的行为是正确的。
根据C++标准,显式特化(template<> void foo<bool>())的优先级高于任何模板重载(包括带Concept约束的模板版本)。当实例化foo<bool>()时,显式特化是直接绑定到bool类型的专属实现,应当被优先选中,不会与带Concept约束的模板重载产生歧义——带Concept约束的template<std::integral> void foo()属于模板重载范畴,而非主模板的特化,两者不在同一决议层级,显式特化的匹配优先级天然更高。
GCC错误地将显式特化与带Concept约束的模板重载视为同级候选者进行歧义判定,违背了标准中关于显式特化优先级的规定。
内容的提问来源于stack exchange,提问作者Jean-Michaël Celerier
相关产品推荐
相关产品推荐

