В С++ требуется ключевое слово typename
, чтобы компилятор мог устранить неоднозначность между вложенными типами и вложенными значениями в шаблонах. Однако существуют определенные ситуации, когда двусмысленность невозможна, например, когда производный класс наследуется от вложенного типа класса.
template <class T>
class Derived : public T::type
{ };
Здесь ключевое слово typename
не требуется и на самом деле даже не разрешено. Это имеет смысл, потому что контекст устраняет двусмысленность. Здесь T::type
должен ссылаться на тип, поскольку вы, очевидно, не можете наследовать от значения.
Я бы подумал, что то же самое верно для параметров шаблона функции.
template <class T>
void foo(const T::type& v)
{
}
В этом случае контекст дает понять, что T::type
должен ссылаться на тип, поскольку параметр функции не может быть значением. Тем не менее, компилятор этого не принимает. Он хочет const typename T::type&
. Это кажется непоследовательным. Почему язык допускает неявное предположение о вложенном типе в контексте наследования, но не в контексте параметров функции? В обоих случаях не может быть двусмысленности, поэтому зачем нужна typename
в одном, а не другом?