Какова цель имени типа в С++

Возможный дубликат:
Официально, для чего предназначено имя типа?

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

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

какова цель двух "имен" во второй строке?

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

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

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


person peterchen    schedule 17.08.2010    source источник
comment
Я должен признаться, что был слегка удивлен, что человек с тегом C++ задал такой простой вопрос о программировании шаблонов. Вы когда-нибудь компилировали с помощью лучшего компилятора, чем Visual Studio? (как в, более совместимом со стандартом)   -  person Matthieu M.    schedule 17.08.2010
comment
@Mathieu: я использовал Watcom C ++ 9.0-10.5, наблюдая, как в нем оживают более тонкие детали C ++, и я использовал Comeau для некоторых тестов, хотя никогда не работал в производстве. Действительно ли здесь заслужено пренебрежительное отношение к VS? --- Ключевой момент, который я упустил, заключался в том, что T::SubType * p будет проанализировано как арифметическое выражение. --- Я не заметил, что у меня есть тег C++, но я знаю, что C++ все еще удивляет меня примерно раз в месяц.   -  person peterchen    schedule 17.08.2010


Ответы (2)


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

Прозрачный как грязь?

person Ben Collins    schedule 17.08.2010
comment
+1 - Чтобы (надеюсь) немного прояснить в шаблоне, если у вас есть Shape::type, компилятор не может определить, является ли тип типом или это переменная/перечисление в Shape. Использование квалификатора имени типа позволяет сообщить компилятору, что это тип. - person RC.; 17.08.2010

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

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

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

person Sadeq    schedule 17.08.2010