Шаблонные параметры: typename и class. Есть ли разница?

Эпиграф:

Не все йогурты одинаково полезны.




Преамбула:
При написании шаблонных параметров обычно принято использовать ключевое слово class, чтобы подчеркнуть, что шаблонный параметр является классом (структурой). Стандарт C++ говорит следующее [п.14.1.2]:

There is no semantic difference between class and typename in a template-parameter.




Из чего можно сделать вывод, что никакой разницы в ключевых словах typename и class при объявлении шаблонных параметров нет.


Амбула:
Намедни необходимо было написать шаблонный класс, параметризованный другим шаблонным классом. Было написано:


template <template  <typename T> typename Cl >


Вот тут и возникла проблема - компилятор VC++ 2010 гордо рапортовал об ошибке:

error C2988: unrecognizable template declaration/definition





Компилятор Intel C++ Compiler 12.0 и также возвращал сообщение об ошибке:

error : expected "class"
template <template <typename T> typename Cl >
                                ^





После повторного чтения стандарта, была выяснена причина. Если подробнее рассмотреть синтаксис шаблонных параметров, то можно заметить, что для параметризации шаблонных параметров можно использовать только ключевое слово class [п.14.1.1]:

template < template-parameter-list > class ...[opt] identifier[opt]
template < template-parameter-list > class identifier[opt] = id-expression





Вобщем, проблема локализована и после корректировки исходного кода до:


template <template  <typename T> class Cl >


компиляция проходит успешно в VC++ 2010 и Intel C++ 12.0.


Мораль:
Не всегда ключевые слова typename и class являются синонимами. При объявлении шаблонного параметра другого шаблонного параметра необходимо использовать только ключевое слово class, вместо typename.
И... проглядывайте стандарт C++;)

For more complete information about compiler optimizations, see our Optimization Notice.