这几乎肯定是Is gcc wrong not diagnose narrowing conversions in non-type template arguments?的副本,但它没有提供令人满意的答案。答案并未解决海湾合作委员会是否在提供诊断方面出错,只是给出了一个有点替代的警示标志。
标准的相关部分:
§14.3.2/ 5
对于整数或枚举类型的非类型模板参数, 转换常量表达式(5.19)中允许的转换是 应用
§5.19/ 3
T类型的转换常量表达式是文字常量 表达式,隐式转换为类型T,其中隐式 在文字常量表达式中允许转换(如果有的话) 隐式转换序列仅包含用户定义的 转化,左值转换(r值)转换(4.1),整体促销 (4.5)和积分转换(4.7),而不是缩小转换次数 (8.5.4)
该标准解决了缩小转换会使程序格式不正确的情况,但这里有一个明显的遗漏,因此编译器不同意(GCC不提供诊断,Clang使此错误,MSVC也不提供诊断。)是标准中有语言说这种情况需要诊断(即它是不正确的)?
#include <array>
int main()
{
std::array<int, -1> a;
}
答案 0 :(得分:3)
截至n3337,措辞已经改变,以表明结果是不正确的。 (§14.3.2/ 5):
对用作非类型模板参数的每个表达式执行以下转换。如果非类型模板参数无法转换为相应模板参数的类型,则程序格式不正确。
由于它指明程序格式错误,并且没有给予相反的特定许可,因此违反此规定需要进行诊断(根据§1.4/ 1):
可诊断规则集包含本国际标准中的所有语法和语义规则,但那些包含“无需诊断”的明确表示法或描述为“未定义行为”的规则除外。
FWIW,请注意,他们还将允许的转换的定义与转换的常量表达式的定义分开 - 可能的转换现在直接列在§14.3.2/ 5中。