Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
Pechkin80
19 / 18 / 7
Регистрация: 14.03.2014
Сообщений: 251
1

Зависимые имена и typename

14.11.2017, 18:58. Просмотров 558. Ответов 26
Метки нет (Все метки)

Не пойму логику зависимых имён. может кто подскажет.
вот есть такой пример:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <typename _T1> class TExternal
{
    typedef _T1 T1; //typename не нужен
    T1 m_external;
    class Tnested
    {
        typedef int T2;
        T2 m_nested; //typename не нужен
    };
    template <typename _T2>
    class Tnested2 {  class Tnested_nested {     };   };
    Tnested2<T1> m_nested1; //typename не нужен
    Tnested::T2 m_nested3; //typename нужен
};
 
int main(int argc, char *argv[])
{
    return 0;
}
Почему для m_nested3 ключевое слово typename требуется, а для m_external нет ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.11.2017, 18:58
Ответы с готовыми решениями:

Оператор typename
Здравствуйте. Делал недавно небольшую программку и столкнулся с одной...

Typename и Class
Между записью template &lt;class T&gt; и template &lt;typename T&gt; нет никакой разницы?

шаблоны и typename в частности
Здравствуйте! Я разбираюсь с ассоциативными контейнерами в с++ - делаю...

Template<typename T> vs auto
template &lt;typename T&gt; vector&lt;T&gt; my_vec1; vector&lt;auto&gt; my_vec2;Какая разница...

Typename перед инстанцированием
В каких случаях перед созданием объекта надо писать typename... И зачем оно там...

26
hoggy
Заблокирован
Эксперт С++
14.11.2017, 19:38 2
Цитата Сообщение от Pechkin80 Посмотреть сообщение
Почему для m_nested3 ключевое слово typename требуется, а для m_external нет ?
http://alenacpp.blogspot.nl/2006/08/typename.html

ps:
Цитата Сообщение от Pechkin80 Посмотреть сообщение
typename _T1
UB
0
Pechkin80
19 / 18 / 7
Регистрация: 14.03.2014
Сообщений: 251
14.11.2017, 19:49  [ТС] 3
hoggy, Не нашёл ответ по вашей ссылки. Прочёл до конца.
0
notAll
455 / 174 / 64
Регистрация: 27.05.2016
Сообщений: 461
Завершенные тесты: 2
14.11.2017, 19:57 4
Pechkin80, по зависимым именам есть интересный пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <typename T>
struct Base
{
    typedef T instantiated_type;
};
 
template <>
struct Base<int>
{
    int instantiated_type = 10.02;
};
 
template <typename T>
struct Derived : Base<T>
{
    void foo()
    {
        Base<T>::instantiated_type;
    }
};
Спрашиваеться: чем являеться instantiated_type в Derived? Типом или значениям?
1
Pechkin80
19 / 18 / 7
Регистрация: 14.03.2014
Сообщений: 251
14.11.2017, 20:07  [ТС] 5
jahdjkhasjdhjah, "Ответ в духе компилятор подумает" не сюда. Не аффторитет тут компилятор))) Пусть думает что хочет.
Случае обязательного применения typename изложены в стандарте ISO 14882:2011: 14.6:

A name used in a template declaration or definition and that is dependent on a template-parameter is
assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified
by the keyword typename.
When a qualified-id is intended to refer to a type that is not a member of the current instantiation (14.6.2.1)
and its nested-name-specifier refers to a dependent type, it shall be prefixed by the keyword typename, forming
a typename-specifier. If the qualified-id in a typename-specifier does not denote a type, the program is illformed.
If a specialization of a template is instantiated for a set of template-arguments such that the qualified-id
prefixed by typename does not denote a type, the specialization is ill-formed. The usual qualified name
lookup (3.4.3) is used to find the qualified-id even in the presence of typename.
A qualified name used as the name in a mem-initializer-id, a base-specifier, or an elaborated-type-specifier
is implicitly assumed to name a type, without the use of the typename keyword. In a nested-name-specifier
that immediately contains a nested-name-specifier that depends on a template parameter, the identifier or
simple-template-id is implicitly assumed to name a type, without the use of the typename keyword. [ Note:
The typename keyword is not permitted by the syntax of these constructs
If, for a given set of template arguments, a specialization of a template is instantiated that refers to a
qualified-id that denotes a type, and the qualified-id refers to a member of an unknown specialization, the
qualified-id shall either be prefixed by typename or shall be used in a context in which it implicitly names a
type as described above
0
jahdjkhasjdhjah
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
14.11.2017, 20:11 6
Цитата Сообщение от notAll Посмотреть сообщение
Спрашиваеться: чем являеться instantiated_type в Derived? Типом или значениям?
А посмотреть выше компилятору слабо? ;-)

Короче, это подсказка компилятору, что это тип, а не внутренняя переменная. Компиляторы еще не настолько умны, как живые программисты.
0
notAll
455 / 174 / 64
Регистрация: 27.05.2016
Сообщений: 461
Завершенные тесты: 2
14.11.2017, 20:15 7
Цитата Сообщение от jahdjkhasjdhjah Посмотреть сообщение
А посмотреть выше компилятору слабо?
Он бы посмотрел, да только он еще не знает чем будет T
0
jahdjkhasjdhjah
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
14.11.2017, 20:24 8
Так на момент создания инстанса T будет известен. ) И применять тогда к нему тот случай, который подходит для этого T

Добавлено через 2 минуты
Вообще, по рукам бить за такие объявления
0
Pechkin80
19 / 18 / 7
Регистрация: 14.03.2014
Сообщений: 251
14.11.2017, 20:29  [ТС] 9
notAll, В вашем случае возможно имеет место not-deduced context для template alias 14.5.7.

ISO/IEC 14882:2011(E) § 7.3.3/19
If a using-declaration uses the keyword typename and specifies a dependent name (14.6.2), the name intro-
duced by the using-declaration is treated as a typedef-name (7.1.3).
0
hoggy
Заблокирован
Эксперт С++
14.11.2017, 20:31 10
Цитата Сообщение от jahdjkhasjdhjah Посмотреть сообщение
Так на момент создания инстанса T будет известен. )
Почему компилируется не объявленная переменная в шаблоне?
0
jahdjkhasjdhjah
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
14.11.2017, 20:48 11
И как ваша ссылка противоречит тому, что я сказал?
0
animefan
119 / 9 / 2
Регистрация: 06.09.2017
Сообщений: 82
14.11.2017, 22:21 12
Цитата Сообщение от Pechkin80 Посмотреть сообщение
Почему для m_nested3 ключевое слово typename требуется, а для m_external нет ?
Потому что T1 эквивалент _T1 и ему, как и _T1, typename не полагается.
0
hoggy
Заблокирован
Эксперт С++
14.11.2017, 23:23 13
Цитата Сообщение от jahdjkhasjdhjah Посмотреть сообщение
И как ваша ссылка противоречит тому, что я сказал?
Цитата Сообщение от jahdjkhasjdhjah Посмотреть сообщение
Так на момент создания инстанса T будет известен. ) И применять тогда к нему тот случай, который подходит для этого T
Почему компилируется не объявленная переменная в шаблоне?
0
Pechkin80
19 / 18 / 7
Регистрация: 14.03.2014
Сообщений: 251
15.11.2017, 00:03  [ТС] 14
notAll, Спасибо, хороший пример, побольше таких. Такие вопросы на всё $$$.
Свою версию ответа своего вопроса выкладываю.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
template <typename _T1> class TExternal_utn
{
public:
    typedef _T1 T1;
    // typename не нужен так как параметр шаблона или его псевдоним
    // не является сам по себе dependent name
    T1 m_res;
    // typename нужен так как является dependent name
    typename
    TExternal_utn<_T1>::T1 m_res2;
    class Tnested
    {
        typedef int T2;
        T2 m_nested; // typename не нужен так как T2 не является dependent name
    };
    template <typename _T2>
    class Tnested2
    {
    public:
        class Tnested_nested {     };
    };
    // typename не нужен
    // Не является dependent name, так как разрешение имён будет выполнено для имени Tnested2
    // в результате unquelified name lookup
    Tnested2<T1> m_nested;
    // typename нужен так явялется зависимым именем
    // и в результате quelified name lookup
    // будет приведено к виду TExternal_utn<_T1>::Tnested2<int>::Tnested_nested m_nested;
    typename
    Tnested2<int>::Tnested_nested m_nested2;
    // typename нужен так явялется зависимым именем
    // и в результате quelified name lookup
    // будет приведено к виду TExternal_utn<_T1>::Tnested::T2 m_nested3;
    typename
    Tnested::T2 m_nested3; //typename nuzen
};
0
animefan
119 / 9 / 2
Регистрация: 06.09.2017
Сообщений: 82
15.11.2017, 01:40 15
Цитата Сообщение от Pechkin80 Посмотреть сообщение
C++
1
2
3
// typename нужен так как является dependent name
typename
    TExternal_utn<_T1>::T1 m_res2;
Цитата Сообщение от http://eel.is/c++draft/temp.dep#def:name,dependent
In an expression of the form:

postfix-expression ( expression-listopt )

where the postfix-expression is an unqualified-id, the unqualified-id denotes a dependent name if
....
Каким образом TExternal_utn<_T1>::T1 — это dependent name, когда оно даже не expression и очевидно не в форме postfix-expression ( expression-listopt )?

Ты, наверное, хотел говорить про dependent type, а не name? Тогда твоё первое утверждение неверно. Параметр темплейта — это depentent type http://eel.is/c++draft/temp.dep#type-9.1
0
Pechkin80
19 / 18 / 7
Регистрация: 14.03.2014
Сообщений: 251
15.11.2017, 01:57  [ТС] 16
animefan, Ох, грусто всё это.
ISO 14882:2011 1.6
Names for syntactic categories have generally been chosen according to the following rules:
— X-name is a use of an identifier in a context that determines its meaning (e.g., class-name, typedefname).
— X-id is an identifier with no context-dependent meaning (e.g., qualified-id).
— X-seq is one or more X’s without intervening delimiters (e.g., declaration-seq is a sequence of declarations).
— X-list is one or more X’s separated by intervening commas (e.g., expression-list is a sequence of
expressions separated by commas).

Не по теме:

А мы уже на ты ?

0
animefan
119 / 9 / 2
Регистрация: 06.09.2017
Сообщений: 82
15.11.2017, 01:58 17
Цитата Сообщение от Pechkin80 Посмотреть сообщение
ISO 14882:2011 1.6
Это вообще к чему?
0
Pechkin80
19 / 18 / 7
Регистрация: 14.03.2014
Сообщений: 251
15.11.2017, 02:01  [ТС] 18
animefan, Вредно читать форум по ночам. Имя это только часть выражения в общем случае и неважно идёт ли речь об имени типа, переменной или чегото ещё.
0
animefan
119 / 9 / 2
Регистрация: 06.09.2017
Сообщений: 82
15.11.2017, 02:04 19
Цитата Сообщение от Pechkin80 Посмотреть сообщение
Вредно читать форум по ночам.
У меня только-только полночь наступила.

Цитата Сообщение от Pechkin80 Посмотреть сообщение
Имя это только часть выражения в общем случае и неважно идёт ли речь об имени типа, переменной или чегото ещё.
Ладно, что ты типы от выражений не отличаешь. Но если ты не видишь, что TExternal_utn<_T1>::T1 это не "of the form: postfix-expression ( expression-listopt )", то это совсем печально.
0
Pechkin80
19 / 18 / 7
Регистрация: 14.03.2014
Сообщений: 251
15.11.2017, 02:07  [ТС] 20
dependent type это частный случай depedentent name. Сама структура глав это подразумевает.

Добавлено через 1 минуту
animefan, Тут идёт речь о разрешении имём. Ну нет тут пока никаких семантических конструкций.
0
15.11.2017, 02:07
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.11.2017, 02:07

Typename в шаблонах класса
В таком шаблоне: template &lt;typename T, int n, bool islong=???&gt; class...

Что означает using typename в шаблоне?
template &lt; typename T &gt; class Class_name { public: using...

В чем отличие typename от class?
Зачем нужно typename В чем отличие от class ?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru