为什么这个模板代码不选择部分专业化

Why does this template code does not select partial specialization?

本文关键字:选择部 专业化 代码 为什么      更新时间:2023-10-16

我有以下代码,我很困惑为什么没有选择专业化。

#include<iostream>
using namespace std;
namespace detail {
struct tag {};
}
template<auto& X, typename Y>
struct s{
static constexpr auto val = 11;
};
template<auto& X>
struct s<X,detail::tag>{
static constexpr auto val = 22;
};
int main()
{
static constexpr long long arr[] = {42ll,47ll};
cout <<  s<arr, detail::tag>::val << endl; //outputs 11, not 22
cout <<  s<arr, int>::val << endl;
}

附言:我不确定我是否正确地专门化了模板,但它可以编译,所以我想它可能很好。

代码格式不正确,编译器应该报告错误。用于非类型引用模板参数的自变量必须是(C++17 14.3.2(

一个常量表达式(5.19(,用于指定具有静态存储持续时间和外部或内部链接的完整对象的地址,或具有外部或内部连接的函数

如果对象可以从同一翻译单元中的其他作用域引用,则该对象具有内部链接;如果对象可以在同一翻译单位和其他翻译单元中从其他作用域中引用,则具有外部链接。模板参数arr在主函数的作用域中声明,仅在此作用域中可见,因此没有链接,不应与任何模板匹配。

当我在我的机器上安装的编译器上尝试它时,clang(6.0.0-1ubuntu2(显示出与问题中相同的行为,而gcc(7.3.0-16ubuntu3(报告arr是一个没有链接的名称。如果我将arr移到函数范围之外(从而使其具有外部链接(,那么两个编译器都会接受代码并给出预期的结果。