Ответ 1
Нет, это не законно. Нет ничего о спецификации std::array
, которая явно предотвращает это, но это незаконно из-за сужения конверсий.
§14.3.2/5:
Для нестандартного шаблона-параметра интегрального или перечисляемого типа преобразования разрешенные в преобразованном постоянном выражении (5.19).
§5.19/3:
Преобразованное константное выражение типа T является литеральным постоянным выражением, неявно преобразованный в тип T, где неявное преобразование (если оно есть) разрешено в литеральном постоянном выражении и неявной последовательности преобразования содержит только определенные пользователем преобразования, преобразования lvalue-to-rvalue (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;