C ++ - значение оператора, объединяющего typedef и typename

В заголовочном файле C ++ я вижу этот код:

typedef typename _Mybase::value_type value_type;

Теперь, как я понимаю, цитирую «Полный справочник по C ++» Шильдта. typename можно заменить ключевым словом class, второе использование typename - сообщить компилятору, что имя, используемое в объявлении шаблона, является именем типа, а не именем объекта.

Точно так же вы можете определить имена новых типов данных с помощью ключевого слова typedef. Фактически вы не создаете новый тип данных, а скорее определяете новое имя для существующего типа.

Однако можете ли вы объяснить, что именно означает приведенная выше строка кода, где typedef и typename объединены. А что означает "::" в заявлении?


person Arvind    schedule 22.08.2013    source источник
comment
typename одинаково используется внутри и снаружи typedef. Более реалистичным (своего рода) примером может быть typedef typename std::vector<T>::iterator Iter;   -  person chris    schedule 22.08.2013
comment
@chris, что именно _Mybase :: value_type и value_type по отдельности и _Mybase :: value_type представляет собой value_type?   -  person Arvind    schedule 22.08.2013
comment
И боже, Шильдт вернулся. Сожги эту книгу прямо сейчас.   -  person chris    schedule 22.08.2013
comment
@Arvind В то время, когда встречается шаблон, вы не знаете приседания о базовом типе. Утверждение, о котором вы говорите, - это языковой механизм, используемый для того, чтобы сообщить компилятору, что эта вещь будет фактически именем типа, когда она будет использована. (И я не могу поверить, что Херби Шилдт все еще пишет. Когда я проверял, вы могли найти его книги только в Библиотеке Конгресса).   -  person WhozCraig    schedule 22.08.2013
comment
@Arvind, :: означает, что он вложен в _Mybase. typedef и typename - это два разных вопроса, на один из которых дан довольно хороший ответ в той ссылке.   -  person chris    schedule 22.08.2013
comment
@ chris - вы правы, но у Шильдта есть одно применение - это фактическая энциклопедия C ++ - не учения, а сухие факты, как на скучном уроке истории. :)   -  person Arvind    schedule 22.08.2013
comment
Прочтите: что это за три несвязанные функции C ++, о которых я не читал в своей книге?   -  person Lightness Races in Orbit    schedule 22.08.2013
comment
@Arvind: К сожалению, многие из этих фактов неверны.   -  person Lightness Races in Orbit    schedule 22.08.2013
comment
Имя типа может быть заменено ключевым словом class lol, false. Удивительно, как часто случайная цитата из произведений Шильдта оказывается неверной.   -  person R. Martinho Fernandes    schedule 22.08.2013
comment
@Arvind: да, если вы думаете об уроке истории о том, как римляне сражались с Чингисханом за контроль над Америкой.   -  person R. Martinho Fernandes    schedule 22.08.2013
comment
@ R.MartinhoFernandes typename может быть заменен классом в контексте простого объявления шаблона, то есть шаблон ‹typename T› может быть заменен шаблоном ‹class T›   -  person pippin1289    schedule 22.08.2013
comment
@ pippin1289, но не в данном случае.   -  person chris    schedule 22.08.2013
comment
@ pippin1289 Я знаю. Это не меняет того факта, что текст вводит вас в заблуждение, и вы думаете, что его можно заменить в данном конкретном контексте. Обратите внимание, как это все в одном предложении и со злоупотреблением запятыми. (Я предполагаю, что наш спрашивающий правильно цитирует)   -  person R. Martinho Fernandes    schedule 22.08.2013
comment
@chris Да, действительно, я просто разъяснял OP, чтобы он мог полностью понять   -  person pippin1289    schedule 22.08.2013


Ответы (2)


typedef определяет новый тип для использования в вашем коде, как сокращение.

typedef typename _MyBase::value_type value_type;
value_type v;
//use v

typename здесь сообщает компилятору, что value_type является типом, а не статическим членом _MyBase.

:: - это область действия типа. Это что-то вроде "находится внутри", так что value_type "находится в" _MyBase ". или также может рассматриваться как содержит.

person pippin1289    schedule 22.08.2013
comment
Обязательно ли здесь «typename»? - person johngreen; 10.05.2016
comment
Это зависит от контекста. Если _MyBase зависит от параметра шаблона, чем да (если _MyBase является типом шаблона), в противном случае этого не должно быть. Если вы не уверены в своем контексте, компилятор поможет вам, выдав ошибку. - person pippin1289; 10.05.2016
comment
зачем typename , когда _MyBase является типом шаблона? и почему typename не нужен, если _MyBase не является типом шаблона? - person David; 08.08.2019
comment
@ V.Wu В общих чертах это связано с тем, что компилятор не может подключаться к типу шаблона до тех пор, пока он не будет использован (создан экземпляр). Итак, для того, чтобы этот синтаксис был действительным, программист должен уточнить, является ли value_type типом, то есть с typename или нет (это переменная-член или метод). - person pippin1289; 09.08.2019

typename говорит, что _Mybase::value_type - это имя типа, поэтому typedef может полагаться на этот факт.

person Paul Evans    schedule 22.08.2013
comment
Что изменится, если я его не добавлю? Он не компилируется, отсутствуют ли какие-то предупреждения? Я думал typedef A B; отлично работает во всех случаях. - person masterxilo; 30.05.2014
comment
Было бы здорово, если бы кто-нибудь мог ответить на комментарий @ masterxilo, потому что я просто думал о том же. - person RastaJedi; 28.02.2016
comment
@RastaJedi По крайней мере, в Visual Studio typename в этом случае не требуется. Неправильно даже указывать это, если класс, который вы в настоящее время определяете, не является шаблоном: typedef int Int; template<typename T> struct B { typedef typename Int IInt; }; в порядке, а typedef int Int; struct B { typedef typename Int IInt; }; - нет. - person masterxilo; 28.02.2016