2010-08-17 3 views
1

Можно создать дубликат:
Officially, what is typename for?Какова цель "TypeName" в C++

Когда я использую

template <typename TMap> 
typename TMap::referent_type * func(TMap & map, typename TMap::key_type key) 
{ ... } 

какова цель этих двух «TYPENAME «на второй линии?

Кажется, что запускает предупреждение о компиляции (VS2008: C4346), но это только «вы утверждаете, что это тип»?

Фактическая проверка, действительно ли тип TMap::referent_type набирается при создании экземпляра шаблона, но по-прежнему существует требование по стандарту C++, но код корректно анализируется.

Есть ли примеры, когда на самом деле требуется имя типа для разрешения двусмысленности? Или есть еще кое-что?

+0

Должен признать, что человек с тегом C++ задал такой базовый вопрос о программировании шаблонов. Вы когда-нибудь компилировались с лучшим компилятором, чем Visual Studio? (как в, более соответствует стандарту) –

+0

@Mathieu: Я использовал Watcom C++ 9.0-10.5, «наблюдая», что в нем оживают мельчайшие детали C++, и я использовал Comeau для некоторых тестов - хотя никогда в производстве. Является ли диссидентство VS действительно заслуженным здесь? --- Ключевое понимание, которое я отсутствовал, заключалось в том, что 'T :: SubType * p' будет анализироваться как арифметическое выражение. --- Я не заметил, что у меня есть тег C++, но я знаю, что C++ все еще удивляет меня примерно раз в месяц. – peterchen

ответ

4

Ключевое слово typename просто сообщает компилятору, что любой идентификатор следует действительному типу. Это важно в шаблонах, потому что компилятор может еще не иметь определений типов, используемых в шаблонах, но вы все же хотите иметь возможность использовать часть определения этого типа (например, как, например, key_type). Если вы не использовали ключевое слово typename, компилятор ошибся на этом символе, потому что он не знает, что это такое. Это часто возникает, когда вы используете экземпляры шаблонов в качестве параметров шаблона.

Очистить как грязь?

+0

+1 - Чтобы (надеюсь) немного разъяснить в шаблоне, если у вас есть Shape :: type, компилятор не может распознать, является ли тип «типом» или переменным/перечислением в Shape. Использование квалификатора typename позволяет сообщить компилятору, что это «тип». –

0

Вы должны использовать typename, когда тип, который вы используете, зависит от другой вещи.

В вашем примере TMap::key_type зависит от аргумента шаблона, а TMap::key_type может быть идентификатором функции или именем переменной или чем-либо еще ... поэтому мы должны обеспечить, чтобы компилятор был типом, не являющимся функцией-членом.

С другой стороны, когда тип, который мы используем, не зависит от других шаблонов, тогда нам не нужно указывать его как typename.