uh *_*per 20
不,这不合法.没有任何关于std::array明确阻止这种情况的规范,但由于缩小了转换次数,这是非法的.
§14.3.2/ 5:
对于整数或枚举类型的非类型模板参数,将应用转换常量表达式(5.19)中允许的转换.
§5.19/ 3:
T类型的转换常量表达式是一个文字常量表达式,隐式转换为类型T,其中隐式转换(如果有)在文字常量表达式中是允许的,而隐式转换序列仅包含用户定义的转换,lvalue-to-除缩小转化次数之外的右值转换(4.1),整数促销(4.5)和积分转换(4.7)(8.5.4)
让GCC抱怨的唯一方法是启用-Wsign-conversion.这是一个已知的错误,他们没有采取任何动作来修复它.
在Clang中,您会收到预期的错误消息:
error: non-type template argument evaluates to -1, which cannot be
narrowed to type 'std::size_t' (aka 'unsigned long') [-Wc++11-narrowing]
std::array<int, -1> arr;
Run Code Online (Sandbox Code Playgroud)
类型std::array是:
template<
class T,
std::size_t N
> struct array;
Run Code Online (Sandbox Code Playgroud)
当初始化第二个模板参数用-1,它是隐式转换为一个非常大的值std::size_t是unsigned(这是用C++非法通过的指出对方的回答,它应诊断).
另一种可能性是你arr的优化了.您可以通过向-fdump-tree-optimizedgcc命令行添加标志来确认这一点.
如果你确保arr没有优化,我希望你得到以下警告:
prog.cpp:5:25: error: size of variable 'arr' is too large
std::array<int, -1> arr;
Run Code Online (Sandbox Code Playgroud)