Почему для частичной специализации в нетиповом аргументе запрещено использовать параметры вложенного шаблона - PullRequest
36 голосов
/ 12 мая 2011

У меня есть этот код

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;

Это хорошо, потому что это больше не параметр типа.Но по какой причине спецификация запрещает более прямую частичную специализацию?

Ответы [ 2 ]

14 голосов
/ 13 мая 2011

Я думаю, что многое из этого является историческим. Нетипичные параметры шаблона изначально вообще не допускались. Когда они были добавлены, было много ограничений. Поскольку люди пробовали разные возможности и подтвердили, что они не вызывают проблем, некоторые ограничения были сняты.

Некоторые из этих первоначальных ограничений остаются ни по какой конкретной причине, за исключением того факта, что никто не удосужился их изменить. Как и там, многие из них можно обойти, поэтому удаление их, как правило, не вызовет особых затруднений. В основном все сводится к вопросу о том, достаточно ли заботился кто-либо об этом конкретном случае, чтобы написать статью о нем.

0 голосов
/ 12 мая 2011

Частичная специализация требует, чтобы аргумент шаблона не-типа разрешался во время компиляции.

На данный момент

template<int N>
struct A<N, !(N % 5)> {
  /* ... */
};

N - это переменная, которая может принимать более одного значения, и компилятор не может точно вычислить N % 5.

Ваш пример создает экземпляр использования

A<25> a;

но вы также можете иметь

A<25> a1;
A<15> a2;

Как компилятор выбирает значение для N в этом сценарии? Он не может и поэтому должен запретить код.

...