Вопрос по стандарту
От: Слава Израиль  
Дата: 03.09.09 06:35
Оценка:
Добрый день.

Хочется написать что-то такое:

template <typename X> //Допустим мы обещаем, что в Х будет определён тип Type
class A
{
private:
    typedef X::Type myType;
/*
..........................
*/
}
template <typename X>
class B : public A<X>
{

   myType myMember;//Будет ли здесь определён тип myType по стандарту
}


Более общий случай:

class A
{
private:
     typedef unsigned int uint;
}

class B: public A
{
    uint bbb;//?????????????????
}



Этот код компилируется в MSVS2008, но не в GCC
Спасибо за внимание
Re: Вопрос по стандарту
От: crable США  
Дата: 03.09.09 07:12
Оценка:
Здравствуйте, Слава, Вы писали:

С>Добрый день.


С>Хочется написать что-то такое:


С>
С>template <typename X> //Допустим мы обещаем, что в Х будет определён тип Type
С>class A
С>{
С>private:
С>    typedef X::Type myType; // перед X::Type нужен typename
С>/*
С>..........................
С>*/
С>}
С>


A::myType закрытый тип класса A, он может использоваться только членами класса A или его друзьями.

С>Более общий случай:


С>
С>class A
С>{
С>private:
С>     typedef unsigned int uint;
С>}

С>class B: public A
С>{
С>    uint bbb;//?????????????????
С>}
С>



С>Этот код компилируется в MSVS2008, но не в GCC


Не надо нас обманывать, этот код не компилируется ни одной из версий MSVC или GCC, хотя бы из-за отсутсвия ; после определения класса. В то, что MSVC2008 позволяет обращаться к закрытым членам класса, тоже не верится, или ты имел в виду, что компилируется шаблонный вариант? Тогда это известная бага MSVC (разных версий): он позволяет писатьв шаблонах практически, что угодно, и будет пытаться копмпилировать это только при инстанцировании этого шаблона.

template <class T>
class Foo
{
public:
  Foo()
  {
      typedef ~~~ +++;
      +++ *x = new ~~~();
  }
};


Впрочем, из-за отсутсвия typename и ; первый вариант тоже не компилируется, даже MSVC2008.
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[2]: Вопрос по стандарту
От: Слава Израиль  
Дата: 03.09.09 07:43
Оценка:
Здравствуйте, crable, Вы писали:

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


С>>Добрый день.


С>>Хочется написать что-то такое:


С>>
С>>template <typename X> //Допустим мы обещаем, что в Х будет определён тип Type
С>>class A
С>>{
С>>private:
С>>    typedef X::Type myType; // перед X::Type нужен typename
С>>/*
С>>..........................
С>>*/
С>>}
С>>


Хорошо, typename.

С>>Этот код компилируется в MSVS2008, но не в GCC


C>Не надо нас обманывать, этот код не компилируется ни одной из версий MSVC или GCC, хотя бы из-за отсутсвия ; после определения класса.

Вопрос теоритический, поэтому код набивался прямо в фаерфоксе.

C>A::myType закрытый тип класса A, он может использоваться только членами класса A или его друзьями.

Хорошо, допустим, что typename/ typedef определены в секции protected.

class A
{
protected:
     typedef unsigned int uint;
};

class B: public A
{
    uint bbb;//?????????????????
};

Можно ли в наследуюшем классе обращаться к типу, определённому в наследуемом без указания имени неследуемого класса:
Так как здесь написано, компилируется в MSVS2008, GCC требует писать A::uint;

Кто-нибудь знает, что говорит стандарт, я не нашёл, но надеюсь найти здесь тех, кто знает где искать (т.е. работает более плотно со стандартом)
Спасибо за внимание
Re[3]: Вопрос по стандарту
От: crable США  
Дата: 03.09.09 08:12
Оценка: 2 (1)
Здравствуйте, Слава, Вы писали:

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


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


С>>>Добрый день.


[snip]

C>>Не надо нас обманывать, этот код не компилируется ни одной из версий MSVC или GCC, хотя бы из-за отсутсвия ; после определения класса.

С>Вопрос теоритический, поэтому код набивался прямо в фаерфоксе.

Это, понятно, просто, я, например, предпочёл бы увидеть минимальный компилируемый/некомпилирыемый пример, чтобы не надо было гадать в чём вопрос (не у все же тут телепаты
Автор: Mazay
Дата: 16.06.09
).

C>>A::myType закрытый тип класса A, он может использоваться только членами класса A или его друзьями.

С>Хорошо, допустим, что typename/ typedef определены в секции protected.

С>
С>class A
С>{
С>protected:
С>     typedef unsigned int uint;
С>};

С>class B: public A
С>{
С>    uint bbb;//?????????????????
С>};
С>

С>Можно ли в наследуюшем классе обращаться к типу, определённому в наследуемом без указания имени неследуемого класса:
С>Так как здесь написано, компилируется в MSVS2008, GCC требует писать A::uint;

Для этого примера, GCC ничего подобного не требует. Это необходимо только для шаблонных классов.


templace <class T>
struct A
{
typedef int MyInt;
};

template <class T>
struct B : public A<T> // Тип базового класса зависит от типа T, пока ещё не известного, т.е. мы не знаем что содержит A<T>
{
  MyInt y; // как, по-твоему, компилятор догадается, что MyInt это тип, определённый в A?
};

struct C : public A<void> // Тип базового класса полностью известен и мы уже знаем, есть там MyInt или нет.
{
  MyInt y;
};



С>Кто-нибудь знает, что говорит стандарт, я не нашёл, но надеюсь найти здесь тех, кто знает где искать (т.е. работает более плотно со стандартом)


Более формально смотри 14.6.2 пункт 3 (как раз твой пример) да и вообще весь 14.6 можно почитать.
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[4]: Вопрос по стандарту
От: crable США  
Дата: 03.09.09 08:26
Оценка:
Здравствуйте, crable, Вы писали:

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


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


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


С>>>>Добрый день.


[snip]

С>>Кто-нибудь знает, что говорит стандарт, я не нашёл, но надеюсь найти здесь тех, кто знает где искать (т.е. работает более плотно со стандартом)


C>Более формально смотри 14.6.2 пункт 3 (как раз твой пример) да и вообще весь 14.6 можно почитать.


Да, ещё нужно добавить, что префикс A:: делает тип зависимым от параметра шаблона и откладывает поиск имени на время инстанцирования (2-х фазный поиск имён). Что такое зависимые типы описано в 14.6.2.1.
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[4]: оффтоп
От: Erop Россия  
Дата: 03.09.09 08:52
Оценка:
Здравствуйте, crable, Вы писали:

C>(не у все же тут телепаты
Автор: Mazay
Дата: 16.06.09
).


Прикольно. Не знал, что та история до КУ добрела
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Вопрос по стандарту
От: rg45 СССР  
Дата: 03.09.09 09:20
Оценка: 1 (1)
Здравствуйте, Слава, Вы писали:

С>...

С>Хорошо, typename.
С>...
С>Хорошо, допустим, что typename/ typedef определены в секции protected.
С>...
С>Можно ли в наследуюшем классе обращаться к типу, определённому в наследуемом без указания имени неследуемого класса?...

Начнем с нешаблонного варианта. Кстати, то что нешаблонный вариант является более общим, чем шаблонный, вопрос весьма спорный. Из сказанного ниже должно быть понятно почему. Итак, использование в наследнике открытого или защищенного типа, объявленного в базовом классе, разрешено автоматом и не требует каких-либо дополнительных объявлений:
class A
{
protected:
  typedef unsigned int uint;
};
class B : public A
{
  uint bbb;
};

Иная ситуация с шаблонными классами. Особенность заключается в том, что от места определения шаблонного класса-наследника до места его использования(инстанцирования) шаблонный *базовый* класс может быть сто раз специализирован. И будет ли присутствовать в этих специализациях упомянутый тип — это большой вопрос. Поэтому компилятор, встретив в производном классе использование незнакомого типа, даже не обязан искать его объявление в базовом классе, он имеет право просто сообщить об ошибке. А исправить эту ошибку можно, использовав using-объявление, которым мы сообщим компилятору, что данный идентификатор *должен* быть определен в базовом классе. Кроме того, нужно не забыть о ключевом слове typename, чтобы компилятор знал также, что этот идентификатор обозначает имя типа:
template <typename X>
class A
{
protected:
  typedef typename X::Type myType;
};

template <typename X>
class B : public A<X>
{
  using typename A<X>::myType;
  myType myMember;
};

С>Кто-нибудь знает, что говорит стандарт, я не нашёл, но надеюсь найти здесь тех, кто знает где искать (т.е. работает более плотно со стандартом)
Стандарт говорит примерно то же. Вот только номера пунктов искать сейчас некогда.
--
Не можешь достичь желаемого — пожелай достигнутого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.