Привет!
Мне нужно в методах классов некоторой иерархии иметь псевдонимы для имен классов — класса, в котором определяются методы и его предка.
Стандартный трюк с typedef работал, пока не появился шаблон — наследник шаблона. Вот это не компилируется.
class A
{
public:
typedef A thisclass;
};
template <typename T>
class B: public A
{
public:
typedef thisclass parentclass;
typedef B thisclass;
};
template <typename T>
class C: public B<T>
{
typedef thisclass parentclass;
typedef C thisclass;
};
Похоже, что стандартный
косяк с dependent и не dependent именами в шаблонах, но не могу придумать синтаксиса, чтобы сделать имя dependent.
Здравствуйте, Slowspeed, Вы писали:
S>Привет! S>Мне нужно в методах классов некоторой иерархии иметь псевдонимы для имен классов — класса, в котором определяются методы и его предка. S>Стандартный трюк с typedef работал, пока не появился шаблон — наследник шаблона. Вот это не компилируется.
S>class A S>{ S>public:
S> typedef A thisclass; S>};
S>template <typename T> S>class B: public A S>{ S>public:
S> typedef thisclass parentclass; S> typedef B thisclass; S>};
S>template <typename T> S>class C: public B<T> S>{ S> typedef thisclass parentclass; S> typedef C thisclass; S>};
S>Похоже, что стандартный S>косяк с dependent и не dependent именами в шаблонах, но не могу придумать синтаксиса, чтобы сделать имя dependent.
Напишите
class C: public B<T>
{
typedef typename B<T>::thisclass parentclass;
typedef C thisclass;
};
class C: public B<T>
{
typedef typename B<T>::thisclass parentclass;
typedef C thisclass;
};
или
class C: public B<T>
{
typedef typename С<T>::thisclass parentclass;
typedef C thisclass;
};
Просто у меня эти тайпдефы добавляются макросом, которому передается имя класса, но не передается имя базового и взять его особо неоткуда.
До второго тайпдефа ведь наверное C<T>::thisclass и B<T>::thisclass одно и то-же?
S>Спасибо! То, что надо!
С>class C: public B<T>
С>{
С> typedef typename B<T>::thisclass parentclass;
С> typedef C thisclass;
С>};
С>и будет вам счастье.
А зачем typedef typename B<T>::thisclass parentclass?
Можно же просто typedef B<T> parentclass?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Slowspeed, Вы писали:
S>Простите за еще один, возможно глупый, вопрос:
S>Есть ли разница писать
S>class C: public B<T> S>{ S>typedef typename B<T>::thisclass parentclass; S>typedef C thisclass; S>};
S>или
S>class C: public B<T> S>{ S>typedef typename С<T>::thisclass parentclass; S>typedef C thisclass; S>};
S>Просто у меня эти тайпдефы добавляются макросом, которому передается имя класса, но не передается имя базового и взять его особо неоткуда. S>До второго тайпдефа ведь наверное C<T>::thisclass и B<T>::thisclass одно и то-же?
S>>Спасибо! То, что надо!
Здравствуйте, Сыроежка, Вы писали:
E>>А зачем typedef typename B<T>::thisclass parentclass? E>>Можно же просто typedef B<T> parentclass?
С>Вообще-то, это зависимое имя. По умолчанию предполагается, что используется не имя типа.
Чего? перечитай код, что ли.
B<T> -- всегда имя типа
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
S>>Есть ли разница писать
S>>class C: public B<T> S>>{ S>>typedef typename B<T>::thisclass parentclass; S>>typedef C thisclass; S>>};
S>>или
S>>class C: public B<T> S>>{ S>>typedef typename С<T>::thisclass parentclass; S>>typedef C thisclass; S>>};
С>Можно использовать оба объявления.
3.3.6 1.3
If reordering member declarations in a class yields an alternate valid program under (1) and (2), the pro- gram is ill-formed, no diagnostic is required.
Здравствуйте, BitField, Вы писали:
BF>3.3.6 1.3 BF>If reordering member declarations in a class yields an alternate valid program under (1) and (2), the pro- gram is ill-formed, no diagnostic is required.
То есть, похоже изначальная идея с использованием и последующим переопределением thisclass неверна.
BitField:
S>>>template <typename T> S>>>class C: public B<T> S>>>{ S>>>typedef typename С<T>::thisclass parentclass; S>>>typedef C thisclass; S>>>};
С>>Можно использовать оба объявления.
BF>3.3.6 1.3 BF>If reordering member declarations in a class yields an alternate valid program under (1) and (2), the pro- gram is ill-formed, no diagnostic is required.
Тут, собственно, и одного (2) достаточно:
A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.
Фактически тут undefined behavior и компилятор, например, вправе считать, что parentclass — это не B<T>, а C<T>.
Здравствуйте, BitField, Вы писали:
BF>Здравствуйте, Сыроежка, Вы писали:
S>>>Есть ли разница писать
S>>>class C: public B<T> S>>>{ S>>>typedef typename B<T>::thisclass parentclass; S>>>typedef C thisclass; S>>>};
S>>>или
S>>>class C: public B<T> S>>>{ S>>>typedef typename С<T>::thisclass parentclass; S>>>typedef C thisclass; S>>>};
С>>Можно использовать оба объявления.
BF>3.3.6 1.3 BF>If reordering member declarations in a class yields an alternate valid program under (1) and (2), the pro- gram is ill-formed, no diagnostic is required.
Да, согласен. Правильно будет использовать вложенное имя для класса B.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Сыроежка, Вы писали:
E>>>А зачем typedef typename B<T>::thisclass parentclass? E>>>Можно же просто typedef B<T> parentclass?
С>>Вообще-то, это зависимое имя. По умолчанию предполагается, что используется не имя типа.
E>Чего? перечитай код, что ли. E>B<T> -- всегда имя типа
Здравствуйте, Сыроежка, Вы писали:
E>>B<T> -- всегда имя типа С>Речь же идет не о B<T>, а о B<T>::thisclass.
Насколько я понял, это по дизайну системы одно и то же.
Просто в нешаблонном случае так удобнее писать макросы было.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Сыроежка, Вы писали:
E>>>B<T> -- всегда имя типа С>>Речь же идет не о B<T>, а о B<T>::thisclass.
E>Насколько я понял, это по дизайну системы одно и то же. E>Просто в нешаблонном случае так удобнее писать макросы было.
Я не знаю, о каком дизайне системы вы говорите. Но typename никакого отношения к B<T> не имеет, а имеет отношение к B<T>::thisclass