Они эквивалентны и взаимозаменяемы в большинстве случаев, и некоторые предпочитают typename, потому что использование ключевого слова class в этом контексте кажется запутанным.
Причина, по которой требуется typename, заключается в тех неоднозначных случаях, когда, например, при использовании template <class T>
вы определяете шаблон следующим образом:
template <class T>
void MyMethod() {
T::iterator * var;
}
и затем по какой-то причине пользователь вашего шаблона решает создать экземпляр класса, как это
class TestObject {
static int iterator; //ambiguous
};
MyMethod<TestObject>(); //error
Становится двусмысленным, каким должен быть var, экземпляром итератора класса или статическим типом int. Поэтому для этих случаев было введено typename, чтобы заставить объект шаблона интерпретироваться как тип.