Почему это не разрешено для частичной специализации в аргументе non-type для использования вложенных параметров шаблона
У меня есть этот код
template<int N, bool C = true>
struct A;
template<int N>
struct A<N, !(N % 5)> {
/* ... */
};
// should work
A<25> a;
То есть, для чисел N
, которые делятся на 5
, компилятор должен использовать частичную специализацию. Но компилятор не примет эту частичную специализацию, потому что Стандарт требует отклонения такого кода, где аргумент непиговой частичной специализации ссылается на параметр и не является просто параметром (например, A<N, N>
). Но в чем причина этого?
Обратите внимание, что я могу просто изменить свой код на более многословный пример и он действительно
template<bool> struct wrap;
template<int N, typename = wrap<true> >
struct A;
template<int N>
struct A<N, wrap<!(N % 5)> > {
/* ... */
};
// should work
A<25> a;
Это прекрасно, потому что это не параметр не-типа больше. Но по какой причине спецификация запрещает более прямую частичную специализацию?
Ответы
Ответ 1
Я думаю, что многие из них историчны. Параметры шаблона непигового типа первоначально не разрешались. Когда они были добавлены, было много ограничений. Поскольку люди пытались использовать разные возможности и подтвердили, что они не вызывали проблем, некоторые ограничения были устранены.
Некоторые из этих первоначальных ограничений остаются без особых причин, кроме того, что никто не потрудился работать над их изменением. Как и там, многие из них могут работать, поэтому их удаление обычно часто не вызывает особых трудностей. В основном, дело доходит до того, что кто-нибудь достаточно заботился об этом конкретном случае, чтобы написать статью об этом.
Ответ 2
Частичная специализация требует, чтобы аргумент шаблона непигового типа был разрешен во время компиляции.
В этот момент
template<int N>
struct A<N, !(N % 5)> {
/* ... */
};
N
- это переменная, которая может принимать более одного значения, и компилятор не может с уверенностью вычислить N % 5
.
В этом примере создается
A<25> a;
но вы также можете иметь
A<25> a1;
A<15> a2;
Как компилятор выбирает значение для N в этом сценарии? Он не может и поэтому должен отклонять код.