Следующая программа компилируется без ошибок или предупреждения с помощью gcc 4.8.1,
-Wall -std=c++11
:
template<unsigned N>
struct A{};
int main(){
A<1-2> a;
(void)a;
return 0;
}
clang 3.3 с теми же параметрами дает эту ошибку:
ошибка: аргумент шаблона не-типа оценивается в -1, который нельзя сузить, чтобы ввести "unsigned int" [-WС++ 11-сужение]
По этот вопрос, он выглядит как gcc настоящая политика, просто чтобы дать предупреждения для сужения конверсий, где Стандарт указывает на ошибки, и где clang дает указанные ошибки. Но в этом случае gcc даже не дает предупреждения.
Ни один из примеров сужения ошибок преобразования, которые Стандарт в § 8.5.4/7 (воспроизведен в этот вопрос) охватывает случай сужения преобразования аргумента шаблона непигового типа, но в § 14.3.2/5 в Стандарте говорится:
Для непигового шаблона-параметра интегрального или перечисляемого типа преобразования, разрешенные в (5.19).
И в § 5.19/3 говорится:
Преобразованное константное выражение типа T является литеральным постоянным выражением, неявно преобразованным в тип T, где неявное преобразование (если оно есть) разрешено в литеральном постоянном выражении и неявное преобразование последовательность содержит только пользовательские преобразования, преобразования lvalue-to-rvalue (4.1), интегральные рекламные акции (4.5), и интегральные преобразования (4.7), кроме сужения преобразований (8.5.4)
(мой акцент).
Это, как мне кажется, означает, что даже по своему собственному критерию gcc виноват вовсе не в диагностике сужение преобразования в этом случае. Я читаю это правильно? Есть ли Контр-аргумент на основе стандартного?
Я задаю вопрос с большим чувством, что просто любопытство. В рекурсивная настройка TMP, диагностика ошибок clang в этом случае будет определять ошибка, в которой аргумент шаблона без знака через 0, тогда как все, что вы получаете от gcc, - это "максимальная глубина реализации шаблона превышена".