Столкнулся с тем что в режиме совместимости с ANSI С++ (/Za), VS2008 перестает видеть члены базового класса, если тот объявлен внутри класса-шаблона. Отсюда вопрос знатокам: это бага маздая или фича ANSI?
template<class A> class CMain
{
//public:
//class CBase
{
//public:
//int m_aaa;
CBase(void) { m_aaa = 0; }
};
//class CTest : public CBase
{
//public:
//
CTest(void)
{
m_aaa = 0; // компилируется только если включено маздаевское расширение языка С++ или если класс CMain не является шаблоном, иначе верещит что m_aaa не объявлен
CBase::m_aaa = 0; // компилируется всегда, в т.ч. и в режиме ANSI С++ (/Za)
}
};
};
Здравствуйте, Аноним, Вы писали:
А>Столкнулся с тем что в режиме совместимости с ANSI С++ (/Za), VS2008 перестает видеть члены базового класса, если тот объявлен внутри класса-шаблона. Отсюда вопрос знатокам: это бага маздая или фича ANSI?
А>template<class A> class CMain
А>{
А> //
А> public:
А> //
А> class CBase
А> {
А> //
А> public:
А> //
А> int m_aaa;
А> CBase(void) { m_aaa = 0; }
А> };
А> //
А> class CTest : public CBase
А> {
А> //
А> public:
А> //
А> CTest(void)
А> {
А> this->m_aaa = 0; // компилируется только если включено маздаевское расширение языка С++ или если класс CMain не является шаблоном, иначе верещит что m_aaa не объявлен
А> CBase::m_aaa = 0; // компилируется всегда, в т.ч. и в режиме ANSI С++ (/Za)
А> }
А> };
А>};
А>
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, Аноним, Вы писали:
А>>Столкнулся с тем что в режиме совместимости с ANSI С++ (/Za), VS2008 перестает видеть члены базового класса, если тот объявлен внутри класса-шаблона. Отсюда вопрос знатокам: это бага маздая или фича ANSI?
NB>простой способ проверить: http://www.comeaucomputing.com/tryitout/ NB>недавно двухфазный поиск имен обсуждался. здесь частный случай.
Поведение соответствует стандарту — базовый класс зависит от параметра шаблона (CMain<T>::Base), имя m_aaa неквалифицированное, поиск в зависимых базовых классах не производится.
Недовно обсуждалось здесь
Здравствуйте, Bell, Вы писали:
А>>>Столкнулся с тем что в режиме совместимости с ANSI С++ (/Za), VS2008 перестает видеть члены базового класса, если тот объявлен внутри класса-шаблона. Отсюда вопрос знатокам: это бага маздая или фича ANSI?
NB>>простой способ проверить: http://www.comeaucomputing.com/tryitout/ NB>>недавно двухфазный поиск имен обсуждался. здесь частный случай.
B>Поведение соответствует стандарту — базовый класс зависит от параметра шаблона (CMain<T>::Base), имя m_aaa неквалифицированное, поиск в зависимых базовых классах не производится. B>Недовно обсуждалось здесь
Здравствуйте, Аноним, Вы писали:
А>Столкнулся с тем что в режиме совместимости с ANSI С++ (/Za), VS2008 перестает видеть члены базового класса, если тот объявлен внутри класса-шаблона. Отсюда вопрос знатокам: это бага маздая или фича ANSI?
А>
А>template<class A> class CMain
А>{
А> //
А> public:
А> //
А> class CBase
А> {
А> //
А> public:
А> //
А> int m_aaa;
А> CBase(void) { m_aaa = 0; }
А> };
А> //
А> class CTest : public CBase
А> {
А> //
А> public:
А> //
А> CTest(void)
А> {
А> m_aaa = 0; // компилируется только если включено маздаевское расширение языка С++ или если класс CMain не является шаблоном, иначе верещит что m_aaa не объявлен
А> CBase::m_aaa = 0; // компилируется всегда, в т.ч. и в режиме ANSI С++ (/Za)
А> }
А> };
А>};
А>
m_aaa = 0; // комп ....
заменить на this->m_aaa=0;
Хотя, имхо, это бред. :] Компилятору шаблон вообще практически по-барабану (главное чтоб синтаксических ошибок небыло) до тех пор пока он не воплощен. А когда он воплощен это уже и не шаблон, а обычный класс. Поэтому что, с точки зрения логики, мешает компилятору увидеть очевидное я не фтыкнул все равно.
Иногда мне кажется что рабочая группа по стандартизации слишком много курит...
ЗЫ Странный форум, создать тему анонимно можно, а писать в ней нет.
night beast:
А>>Столкнулся с тем что в режиме совместимости с ANSI С++ (/Za), VS2008 перестает видеть члены базового класса, если тот объявлен внутри класса-шаблона. Отсюда вопрос знатокам: это бага маздая или фича ANSI?
NB>простой способ проверить: http://www.comeaucomputing.com/tryitout/
Здравствуйте, Masterkent, Вы писали:
А>>>Столкнулся с тем что в режиме совместимости с ANSI С++ (/Za), VS2008 перестает видеть члены базового класса, если тот объявлен внутри класса-шаблона. Отсюда вопрос знатокам: это бага маздая или фича ANSI?
NB>>простой способ проверить: http://www.comeaucomputing.com/tryitout/
M>Что именно проверить?
соответствие кода стандарту. в большинстве случаев комо не врет.
night beast:
NB>>>простой способ проверить: http://www.comeaucomputing.com/tryitout/
M>>Что именно проверить?
NB>соответствие кода стандарту. в большинстве случаев комо не врет.
Здравствуйте, Masterkent, Вы писали:
M>>>Что именно проверить?
NB>>соответствие кода стандарту. в большинстве случаев комо не врет.
M>Но иногда всё-таки врёт.
ctor: C>Компилятору шаблон вообще практически по-барабану (главное чтоб синтаксических ошибок небыло) до тех пор пока он не воплощен.
Компилятор компилятору рознь.
C++03 — 14.6/7:
If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.
Семантические ошибки могут диагностироваться на этапе анализа определения шаблона. Кроме того, в данном случае синтаксическому разбору препятствует тот факт, что CBase можно специализировать отдельно от всего остального:
template <>
class CMain<int>::CBase
{
};
(т.е. в базовом классе m_aaa может и не быть). C>Иногда мне кажется что рабочая группа по стандартизации слишком много курит...
Мне тоже В комитете столько запутанных правил понавыдумывали, что они там, бедненькие, сами в них разобраться не могут.
Скрытый текст
Из того же С++03 — 14.6/7:
int j;
template<class T> class X {
// ...void f(T t, int i, char* p)
{
t = i; // diagnosed if X::f is instantiated
// and the assignment to t is an error
p = i; // may be diagnosed even if X::f is
// not instantiated
p = j; // may be diagnosed even if X::f is
// not instantiated
}
void g(T t) {
+; // may be diagnosed even if X::g is
// not instantiated
}
};
Обратите внимание на последний комментарий. Данная ошибка не просто может быть диагностирована, она обязана диагностироваться, т.к. последовательность токенов
void g(T t) { +; }
синтаксически не является объявлением функции и, как следствие, в этом примере вообще нет определения шаблона. Когда эту тему обсуждали на comp.std.c++ (Confused about ill-formed templates), два члена комитета высказали мнение о том, что диагностика в данном случае не требуется, однако доказать свою точку зрения, опираясь на нормативный текст стандарта, они так и не смогли.
Про неразбериху с зависимыми базовыми классами (DR 515, issue 1005) я, вроде, где-то тут раньше рассказывал.
Возможно у меня какой-то топорный подход, но он имеет право быть, ибо это классическое противостояние производителя и потребителя. С одной стороны разработчики стандарта пытаются создать некую идеальную конструкцию (что, априори, невозможно в этом мире), которая будет обладать кучей возможностей (востребованность которых порой сомнительна, хотя это глубоко имхо) и которую можно и так крутануть, и эдак поставить. С другой стороны мне, простому бюргеру, большая часть всего этого вообще фиолетова, но просто отмахнуться от этого я не могу. Наоборот, я должен держать всю эту сфероконическую муть в голове, и бороться с ней, чтоб она там применив что-нить "по умолчанию" не загадила мне код.
Поэтому, в данном случае, думаю было бы лучше компилятору не бежать впереди паровоза. Предварительная проверка? Хорошо, но пусть проверяет только то, на что можно дать однозначный ответ — это работать не будет при любых параметрах.
Ведь смотрите что получается: если класс (который даже не является шаблоном) я определил, например, в глобальном пространстве, то у него один код, а если внутри шаблона, то код должен быть уже другой. Ну разве это гуд?
Здравствуйте, ctor, Вы писали:
C>Ведь смотрите что получается: если класс (который даже не является шаблоном) я определил, например, в глобальном пространстве, то у него один код, а если внутри шаблона, то код должен быть уже другой. Ну разве это гуд?
Ну, строго говоря, вложенный класс может быть шаблоном за счёт применения шаблонных параметров обрамляющего класса.
P.S: А товарищи из комитета жадные, не говорят где берут такую траву Если серьёзно, могли бы вместо этой голиматьи с новым синтаксисом декларации функций (одна отмазка почему ретурн тайп переставлен в конец чего стоит) стандартизировать ABI. Реально такое впечатление, что у них там начали править бал теоретики не от мира сего. Или индусы...