std::iterator_traits<Iter>::value_type
От: Аноним  
Дата: 19.08.04 07:23
Оценка:
Здравствуйте!
Не компилируется пример из книги "Thinking in C++".
Компилятор VC6.

Такой код

//: C06:PrintSequence.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Prints the contents of any sequence.
#ifndef PRINTSEQUENCE_H
#define PRINTSEQUENCE_H
#include <algorithm>
#include <iostream>
#include <iterator>

template<typename Iter>
void print(Iter first, Iter last, const char* nm = "",
           const char* sep = "\n",
           std::ostream& os = std::cout) {
  if(nm != 0 && *nm != '\0')
    os << nm << ": " << sep;
  typedef typename 
    std::iterator_traits<Iter>::value_type T;
  std::copy(first, last, 
            std::ostream_iterator<T>(std::cout, sep));
  os << std::endl;
}
#endif // PRINTSEQUENCE_H ///:~


должен отпечатать вектор — ошибки компиляции (и с родным СТЛ-ем и с СТЛ-Портом).
Путём обрезания установлено, что даже

template<typename Iter>
void print(Iter first, Iter last, std::ostream& os, const char* sep = "\n") 
{
    typedef typename std::iterator_traits<Iter>::value_type T;
//    std::copy(first, last, std::ostream_iterator<T>(std::cout, sep));
    os << std::endl;
}


это не компилируется, т.е. проблема здесь —
typedef typename std::iterator_traits<Iter>::value_type T;


Подскажите пожалуйста — что можно сделать?

PS. Для теста: безбожно порезав пример — можно получить — в самом простом виде...

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

template<typename Iter>
void print(Iter first, Iter last) {
  typedef typename std::iterator_traits<Iter>::value_type T;
//  std::copy(first, last, std::ostream_iterator<T>(std::cout, sep));
  std::cout << std::endl;
}

void main()
{
    std::vector<int> v;
    print(v.begin(),v.end());
}
Re: std::iterator_traits<Iter>::value_type
От: Glоbus Украина  
Дата: 19.08.04 07:38
Оценка:
Здравствуйте, Аноним, Вы писали:

Хм...похоже ваще на какую-то ошибку компилятора
Не совсем понятно зачем ты тут iterator_traits юзаешь — можно как мне кажется упростить до вот такого

template<typename Iter>
void print(Iter first, Iter last) 
{
    std::copy(first, last, std::ostream_iterator<typename Iter::value_type>(std::cout, "\n"));
    std::cout << std::endl;
}


Прадва вижы 6-е и такое тоже не хавают
Удачи тебе, браток!
Re: std::iterator_traits<Iter>::value_type
От: korzhik Россия  
Дата: 19.08.04 07:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Компилятор VC6.

А>PS. Для теста: безбожно порезав пример — можно получить — в самом простом виде...
А>
А>#include <algorithm>
А>#include <iostream>
А>#include <iterator>
А>#include <vector>

А>template<typename Iter>
А>void print(Iter first, Iter last) {
А>  typedef typename std::iterator_traits<Iter>::value_type T;
А>//  std::copy(first, last, std::ostream_iterator<T>(std::cout, sep));
А>  std::cout << std::endl;
А>}

А>void main()
А>{
А>    std::vector<int> v;
А>    print(v.begin(),v.end());
А>}


похоже дело в том, что в твоей системе итератор для вектора является указателем и для структуры iterator_traits нет специализации для указателя.
Re[2]: std::iterator_traits<Iter>::value_type
От: Аноним  
Дата: 19.08.04 07:52
Оценка:
Здравствуйте, Glоbus, Вы писали:

G>Здравствуйте, Аноним, Вы писали:


G>Хм...похоже ваще на какую-то ошибку компилятора

G>Не совсем понятно зачем ты тут iterator_traits юзаешь

Это не я его юзаю — в книге пример такой был...

G> — можно как мне кажется упростить до вот такого

собственно — я закомментировал СОРУ — чтобы выделить проблему — потому что вопрос с ostream_iterator-ом который я задавал чуть раньше так и не был решён...

G>
G>template<typename Iter>
G>void print(Iter first, Iter last) 
G>{
G>    std::copy(first, last, std::ostream_iterator<typename Iter::value_type>(std::cout, "\n"));
G>    std::cout << std::endl;
G>}

G>


G>Прадва вижы 6-е и такое тоже не хавают


А кто хавает? Переносить всё на другой компилятор? На какой?
или может есть какое-то решение для вэцэ6?
Re[2]: std::iterator_traits<Iter>::value_type
От: Аноним  
Дата: 19.08.04 07:53
Оценка:
Здравствуйте, korzhik, Вы писали:

K>Здравствуйте, Аноним, Вы писали:


А>>Компилятор VC6.

А>>PS. Для теста: безбожно порезав пример — можно получить — в самом простом виде...
А>>
А>>#include <algorithm>
А>>#include <iostream>
А>>#include <iterator>
А>>#include <vector>

А>>template<typename Iter>
А>>void print(Iter first, Iter last) {
А>>  typedef typename std::iterator_traits<Iter>::value_type T;
А>>//  std::copy(first, last, std::ostream_iterator<T>(std::cout, sep));
А>>  std::cout << std::endl;
А>>}

А>>void main()
А>>{
А>>    std::vector<int> v;
А>>    print(v.begin(),v.end());
А>>}


K>похоже дело в том, что в твоей системе итератор для вектора является указателем и для структуры iterator_traits нет специализации для указателя.


видимо да ... и как мне быть? что изменить?
Re[3]: std::iterator_traits<Iter>::value_type
От: Glоbus Украина  
Дата: 19.08.04 08:00
Оценка:
Здравствуйте, Аноним, Вы писали:


G>>Прадва вижы 6-е и такое тоже не хавают


А>А кто хавает? Переносить всё на другой компилятор? На какой?

А>или может есть какое-то решение для вэцэ6?

Точно хавают вижы 7.1 А переносить там ваще 2 сек.
Удачи тебе, браток!
Re[3]: std::iterator_traits<Iter>::value_type
От: Glоbus Украина  
Дата: 19.08.04 08:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А> видимо да ... и как мне быть? что изменить?


Можно ручками самому напистьа специализвцию для указателей. Хотя ваще странно что в 6-х вижах такого нету.
Вот из мсдн например код

template<class Type>
   struct iterator_traits<Type*> {
   typedef random_access_iterator_tag iterator_category;
   typedef Type value_type;
   typedef ptrdiff_t difference_type;
   typedef Type *pointer;
   typedef Type& reference;
   };
Удачи тебе, браток!
Re[3]: std::iterator_traits<Iter>::value_type
От: korzhik Россия  
Дата: 19.08.04 08:14
Оценка:
Здравствуйте, Аноним, Вы писали:

K>>похоже дело в том, что в твоей системе итератор для вектора является указателем и для структуры iterator_traits нет специализации для указателя.


А> видимо да ... и как мне быть? что изменить?


Надо добавить специализацию структуры iterator_traits для указателей и для указателей на константу
это называется частичная специализация по виду аргумента шаблона.
VC 6.0 не поддерживает частичную специализацию.
Как быть не знаю. Возможно есть какой-нибудь трюк.
Re[4]: std::iterator_traits<Iter>::value_type
От: Аноним  
Дата: 19.08.04 08:19
Оценка:
Здравствуйте, Glоbus, Вы писали:

G>Здравствуйте, Аноним, Вы писали:


А>> видимо да ... и как мне быть? что изменить?


G>Можно ручками самому напистьа специализвцию для указателей. Хотя ваще странно что в 6-х вижах такого нету.

G>Вот из мсдн например код

G>
G>template<class Type>
G>   struct iterator_traits<Type*> {
G>   typedef random_access_iterator_tag iterator_category;
G>   typedef Type value_type;
G>   typedef ptrdiff_t difference_type;
G>   typedef Type *pointer;
G>   typedef Type& reference;
G>   };

G>



А нельзя ли подробней — что делать-то? Куда это писать, для кого, что доопределять...
Re[4]: std::iterator_traits<Iter>::value_type
От: korzhik Россия  
Дата: 19.08.04 08:32
Оценка:
Здравствуйте, korzhik, Вы писали:

K>Надо добавить специализацию структуры iterator_traits для указателей и для указателей на константу

K>это называется частичная специализация по виду аргумента шаблона.
K>VC 6.0 не поддерживает частичную специализацию.
K>Как быть не знаю. Возможно есть какой-нибудь трюк.

как всегда в boost'е нашлось решение:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

#include "boost/detail/iterator.hpp"

template<typename Iter>
void print(Iter first, Iter last) 
{
    typedef typename boost::detail::iterator_traits<Iter>::value_type T;
    std::cout << std::endl;
}

void main()
{
    std::list<int> v;
    print(v.begin(),v.end());
}
Re[5]: std::iterator_traits<Iter>::value_type
От: Glоbus Украина  
Дата: 19.08.04 08:34
Оценка: 2 (1)
Здравствуйте, Аноним, Вы писали:


G>>
G>>template<class Type>
G>>   struct iterator_traits<Type*> {
G>>   typedef random_access_iterator_tag iterator_category;
G>>   typedef Type value_type;
G>>   typedef ptrdiff_t difference_type;
G>>   typedef Type *pointer;
G>>   typedef Type& reference;
G>>   };

G>>



А>А нельзя ли подробней — что делать-то? Куда это писать, для кого, что доопределять...


Собственно вышеприведеднный код можешь прямо целиком без изменений вставить в какой-нить h-файл. То есть если посмотреть на него то можно видеть что в терминах итератора как указателя value_type который тебе нужен определячется через тип, которым параметризуется шаблон, ну и т.д.
Удачи тебе, браток!
Re[5]: std::iterator_traits<Iter>::value_type
От: korzhik Россия  
Дата: 19.08.04 08:40
Оценка: 2 (1)
Здравствуйте, korzhik, Вы писали:

>как всегда в boost'е нашлось решение:

K>
K>#include <algorithm>
K>#include <iostream>
K>#include <iterator>
K>#include <vector>

K>//#include "boost/detail/iterator.hpp"
#include "boost/iterator/iterator_traits.hpp" // лучше так

K>template<typename Iter>
K>void print(Iter first, Iter last) 
K>{
K>    typedef typename boost::detail::iterator_traits<Iter>::value_type T;
K>    std::cout << std::endl;
K>}

K>void main()
K>{
K>    std::list<int> v;
K>    print(v.begin(),v.end());
K>}
K>
Re[5]: std::iterator_traits<Iter>::value_type
От: KoY  
Дата: 19.08.04 08:48
Оценка:
Здравствуйте, korzhik, Вы писали:

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


K>>Надо добавить специализацию структуры iterator_traits для указателей и для указателей на константу

K>>это называется частичная специализация по виду аргумента шаблона.
K>>VC 6.0 не поддерживает частичную специализацию.
K>>Как быть не знаю. Возможно есть какой-нибудь трюк.

K>как всегда в boost'е нашлось решение:

K>
K>#include <algorithm>
K>#include <iostream>
K>#include <iterator>
K>#include <vector>

K>#include "boost/detail/iterator.hpp"

K>template<typename Iter>
K>void print(Iter first, Iter last) 
K>{
K>    typedef typename boost::detail::iterator_traits<Iter>::value_type T;
K>    std::cout << std::endl;
K>}

K>void main()
K>{
K>    std::list<int> v;
K>    print(v.begin(),v.end());
K>}
K>



Благодарю. Однако — будет ли Буст успешно работать с ВэЦэ6?
Re[6]: std::iterator_traits<Iter>::value_type
От: korzhik Россия  
Дата: 19.08.04 08:54
Оценка:
Здравствуйте, KoY, Вы писали:

KoY>Благодарю.

это ты зарегистрировался что-ли? Молодец.

KoY>Однако — будет ли Буст успешно работать с ВэЦэ6?

какие-то библиотеки из boost'а будут работать, какие-то нет.
пример который я дал будет.
Re[6]: std::iterator_traits<Iter>::value_type
От: KoY  
Дата: 19.08.04 09:08
Оценка:
Здравствуйте, Glоbus, Вы писали:

G>Здравствуйте, Аноним, Вы писали:



G>>>
G>>>template<class Type>
G>>>   struct iterator_traits<Type*> {
G>>>   typedef random_access_iterator_tag iterator_category;
G>>>   typedef Type value_type;
G>>>   typedef ptrdiff_t difference_type;
G>>>   typedef Type *pointer;
G>>>   typedef Type& reference;
G>>>   };

G>>>



А>>А нельзя ли подробней — что делать-то? Куда это писать, для кого, что доопределять...


G>Собственно вышеприведеднный код можешь прямо целиком без изменений вставить в какой-нить h-файл. То есть если посмотреть на него то можно видеть что в терминах итератора как указателя value_type который тебе нужен определячется через тип, которым параметризуется шаблон, ну и т.д.



А нельзя ли ещё полее подробней, с примером?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.