Typename c что это
Перейти к содержимому

Typename c что это

  • автор:

typename

В определениях шаблонов typename предоставляется указание компилятору о том, что неизвестный идентификатор является типом. В списках параметров шаблона используется для указания параметра типа.

Синтаксис

typename identifier ;

Замечания

typename Ключевое слово необходимо использовать, если имя в определении шаблона — это полное имя, зависящее от аргумента шаблона; необязательно, если полное имя не зависит. Дополнительные сведения см. в разделе «Шаблоны» и «Разрешение имен».

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

template class C1 : typename T::InnerType // Error - typename not allowed. <>; template class C2 : A // typename OK. <>; 

Ключевое слово typename также можно использовать вместо class списков параметров шаблона. Например, следующие операторы семантически эквивалентны:

template. template. 

Пример

// typename.cpp template class X < typename T::Y m_y; // treat Y as a type >; int main()

Что значит typename?

typedef я знаю.
typename — не уверен что понимаю это ключевое слово. Вне template как я понял используется для помощи компилятору в определении типа.
а что происходит дальше std::stack::container_type::iterator ? разве у стека есть итератор?

  • Вопрос задан более двух лет назад
  • 572 просмотра

Комментировать
Решения вопроса 1

Nipheris

Станислав Макаров @Nipheris Куратор тега C++

1. typename в данном случае нужен компилятору только как подсказка от разработчика, что последующий идентификатор (т.е. std::stack::container_type::iterator ) — это действительно имя типа. Подсказка нужна потому, что этот typedef вероятно находится также в шаблоне, и мы ещё не знаем, во что конкретно инстанциируется шаблон std::stack (в этом случае говорят, что container_type «is dependent on a template-parameter» — пока не инстанциируем std::stack, не узнаем).

2. Member-тип container_type эквивалентен типу нижележащего контейнера (т.к. std::stack — это адаптер под интерфейс стека, а не реальный контейнер, реальный контейнер для хранения вы выбираете вторым параметром шаблона, по-умолчанию это std::deque).

3. Вот у std::deque итератор действительно есть.

Зачем надо писать typename для уточнения типа?

@fori1ton: там не аналогичный пример. Насколько я понял, ОП спрашивает зачем в этом коде сделан typename.

25 июл 2013 в 13:16

Подробное описание находится по ссылке представленной @fori1ton. Если кратко, то компилятор не знает, что означает const_iterator . Синтаксис схож как для переменной, так и для объявления типов ( typedef ). Оператор typename говорит, что это имя типа (не переменная).

25 июл 2013 в 13:17

@Expert: а что может означать строка T::const_iterator pos кроме как не объявление типа? Не T::const_iterator * pos , а именно T::const_iterator pos ? Компилятор не знает что именно такое T::const_iterator, но что здесь можно предположить как не тип? Помоему в этом вопрос заключается. Сам я склоняюсь к тому, что это, если не ошибаюсь, требование стандарта.

25 июл 2013 в 13:25

@fori1ton, читал ещё давно, но тут же нету звездочки как подметил @fogbit. То есть компилятор не может определить какой тип туда попадет и это делается в рантайм? Но даже если и так, то без typename выйдет же T(тип)::const_iterator(имя переменной) pos(имя переменной), но такое объявление вызовет ошибку. Если есть строчка в стандарте, в которой сказано о необходимости typename в такой ситуации, то зачем она нужна? Ведь компилятор именно в этом случае может и сам справится.

25 июл 2013 в 14:08

@Robert Pinkman: непосредственно тип выводится в момент инстанса шаблона в коде, т.е. в compile-time. C шаблонами вообще всё происходит в compile-time, если не ошибаюсь. Подозреваю что Стандарт не делает различий в ситуациях, а просто декларирует что если есть объявление типа, зависящего от шаблона в любом контексте, то пиши перед ним typename .

25 июл 2013 в 14:45

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Проблема в том, что T::const_iterator — зависимое имя: оно зависит от параметра шаблона T . В этой точке компилятор не знает, каким будет T , и не может предсказать, будет ли T::const_iterator именем типа или, например, именем статического поля или вообще шаблона. Поэтому он и не пытается угадать, и предполагает, что это поле.

Если же ему подсказать, он будет предполагать, что T::const_iterator — это тип, и поймёт, что

typename T::const_iterator pos; 

Почему же компилятор не может подождать с выяснением смысла выражения T::const_iterator до того момента, когда тип T будет уже известен (то есть, до момента разворачивания шаблона с конкретным типом T )? А вот почему: на момент применения шаблона тип T имеет право быть ещё не определён! И ещё он может зависеть от самого шаблона. Так что откладывать выяснение смысла выражения нельзя. Пример:

template class comparable  < bool compare(T& other) < return this == other; >>; class length : public comparable // в этой точке для comparable // тип T ещё не известен полностью! < . 

Пример кода, иллюстрирующего «скользкие» моменты, приведён ниже. Он не компилируется gcc (так как нету полагающегося по стандарту typename ), но более либеральный MSVC 2012 его компилирует и выполняет.

typename для того и нужен, чтобы исключить подобные сюрпризы.

#include "stdafx.h" // нужно для MSVC #include using namespace std; template struct A < void f() < // если T::iterator - тип, это предварительное объявление функции // если T::iterator - число, это объявление переменной с инициализацией int x(T::iterator); >void g() < int x = 5; < // если T::iterator - шаблон, принимающий числовой аргумент, // это инстанциация шаблона в переменную x, перекрывающую x // за фигурными скобками // если T::iterator -- экземпляр класса с перегруженным оператором x; // Кто-то всё ещё сомневается, что C++ - непредсказуемый язык? > > >; struct T1 < typedef int iterator; >; struct T2 < static const int iterator = 5; >; struct T3 < templatestruct iterator < iterator() < cout >; >; struct T4 < struct Titerator < Titerator operator < (int value) < cout bool operator > (int value) < cout " >; static Titerator iterator; >; T4::Titerator T4::iterator = T4::Titerator(); int main(int argc, char* argv[]) < Aa1; a1.f(); A a2; a2.f(); A a3; a3.g(); A a4; a4.g(); return 0; > 

Результат работы таков:

constructing template with C = 0
in operator < 0
in operator > 5

Typename c что это

Во всех примерах шаблонов у Страуструпа пишется:

template class T> …

Но кроме этого есть еще ключевое слово typename, и можно написать так:

template typename T> …
template struct T>…

или не дай бог так

template union T>…

Ну и так далее. Как правильно делать и зачем нужен typename?

Re: Зачем нужен typename?

От: Lorenzo_LAMAS
Дата: 26.04.05 10:59
Оценка:

Здравствуйте, Ignoramus, Вы писали:

I>Во всех примерах шаблонов у Страуструпа пишется:

I>

template class T> …

Да, как он сам резонно замечает, он использует такой стиль ради краткости.

I>Но кроме этого есть еще ключевое слово typename, и можно написать так:

I>

template typename T> …

Да, можно и так. А вот например, как в книге Гуртового и Абрамса они мотивируют то, что они используют (для примеров в книге class) — чтобы в таком случае templateи т.д. объявление параметра не-типа явно отличалось от параметра — типа.

I>а еще так?

I>

template struct T>…

Так нельзя. Хотя Стен Липман в "Inside C++ object model" говорит, что ради шутки он в своем cfront'е такое добавлял.

I>или не дай бог так

I>

template union T>…

Так нельзя.

I>Ну и так далее. Как правильно делать и зачем нужен typename?

Делать можно как угодно, ибо в данном случае typename и class — равнозначны. Но вот, например, при объявление шаблона параметра шаблона можно использовать уже только class — templateclass A>.
А еще есть и другое использование typename, для указанию компилятору, что зависимое имя — имя типа, но об этом ты уж либо у Бьярна почитай, либо в форуме поищи — было здесь мнооого раз.

Of course, the code must be complete enough to compile and link.
Re: Зачем нужен typename?

От: jazzer Skype: enerjazzer
Дата: 26.04.05 11:00
Оценка:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *