LINUX.ORG.RU

почему компилятор не видит member type базового класса?

 


0

2

вот этот код приводит

template<class Cont, class Iter=typename Cont::iterator>
class my_iterator: public std::iterator_traits<Iter> {
 Iter it;
 // ...
public:
 reference operator*() const {return *it;} // error
 // ...
};
приводит к ошибке
   
error: ‘reference’ does not name a type

вот так ошибка пропадает

  typename std::iterator_traits<Iter>::reference operator*() const {return *it;}
но, я наследовал свой класс от iterator_traits чтобы пользоваться его member type и не прописывать в каждом операторе такие вот выражения.

Почему возникает ошибка? и как правильно унаследоваться от iterator_traits?



Последнее исправление: CYB3R (всего исправлений: 1)

вижу, что библиотеке пишется вот такой вот код:

typedef iterator_traits<_Iterator>  __traits_type;
typedef typename __traits_type::difference_type difference_type;
typedef typename __traits_type::pointer  pointer;
typedef typename __traits_type::reference  reference;
это костыль? или так положено, тогда почему?

linux276
() автор топика
Ответ на: комментарий от linux276

Ну ты можешь написать вот так:

typename my_iterator<Cont>::reference operator*() const {return *it;}

Просто reference нельзя потому что имя должно быть зависимым. Можешь почитать тут, например. Там и на стандарт ссылаются.

Кстати, можно наследоваться сразу от std::iterator, а не от iterator_traits.

DarkEld3r ★★★★★
()
Последнее исправление: DarkEld3r (всего исправлений: 1)
Ответ на: комментарий от DarkEld3r

спасибо, понятно, ограничения предка с параметром )

typedef более лаконичным будет

linux276
() автор топика
Ответ на: комментарий от anonymous

Объясните про зависимые типы в новых стандартах - так как в MSVC2015 CTP5 все компилится и работает, а вроде как не должно

Uter
()
Ответ на: комментарий от Uter

так как в MSVC2015 CTP5 все компилится и работает, а вроде как не должно

Там шаблоны немного иначе раскрываются (насколько знаю, это нарушает какие-то пункты стандарта, но какие конкретно не скажу и искать лень). Если на пальцах, то смысл следующий: компилятор должен проводить определённую диагностику до «раскрытия» (instantiation) шаблона. Ну а дальше - компилятор не смотрит на «зависимые имена» когда рассматриваются независимые, в данном случае, оператор разыменования. ГЦЦ и кланг так и делают, поэтому выдают ошибку ещё до конкретизации шаблона. Вот тут мы шаблон не используем, а ошибка есть.

MSVC на всё это забивает и поэтому в шаблонах можно писать полную ерунду и компилятору будет пофиг до тех пор пока не попробуешь шаблон «реально использовать». То есть дело даже не в зависимых типах, а просто в особенностях реализации. По крайней мере, раньше было именно так.

DarkEld3r ★★★★★
()
Последнее исправление: DarkEld3r (всего исправлений: 1)
Ответ на: комментарий от DarkEld3r

Там шаблоны немного иначе раскрываются

У них там вообще свой стандарт с блекджеком. А typename там (у МС) необязателен, потому что там компиляция по другому проходит. И на момент конпеляции этого кода с разворотом шаблона, компилер уже знает его типы/методы/поля.

На конфе как-то довелось побывать, там один хрен из МС рассказывал. Кстати там можно какой-то варнинг воткнуть, чтоб он за такой год по рукам бил.

anonymous
()
Ответ на: комментарий от anonymous

Да, нашел, бьет при отключенных расширениях (/Za). Где почитать про эту шмагию (в том плане - как (и если есть - почему) оно устроено внутри)?

Uter
()
Последнее исправление: Uter (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.