Jea*_*ier 6 c++ template-specialization language-lawyer explicit-specialization c++-concepts
考虑以下代码:
#include<concepts>
template<typename>
void foo() { }
template<std::integral>
void foo() { }
template<>
void foo<bool>() { }
int main() { foo<bool>(); }
Run Code Online (Sandbox Code Playgroud)
它在最近的 Clang 和 MSVC 下编译没有问题,但在 GCC 下编译没有问题(godbolt 链接)
使用 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() { }
| ^~~
Run Code Online (Sandbox Code Playgroud)
哪个编译器是正确的?我想说 GCC 是错误的,因为通过概念进行的专业化(这使代码仍然通用)和来自用户的实际显式专业化之间不应该有任何歧义,用户应该始终获得优先权。
为了确定您的显式专业化引用了两个函数模板中的哪一个,将执行根据[temp.deduct.decl]foo的模板参数推导,并应用函数模板的部分排序来查找唯一的最佳匹配。
在您的情况下,针对两个候选者的模板参数推导将成功,但模板的部分排序应该成功确定第二个模板为更好的匹配,因为它比第一个模板受到更多限制。(根据[temp.func.order]/6.4和 [temp.constr.order]/3.2)。
所以,是的,我想说海湾合作委员会在这里是错误的。它似乎没有(完全)考虑函数模板部分排序。