ostream << Итератор, C ++ - PullRequest
       41

ostream << Итератор, C ++

1 голос
/ 09 октября 2011

Я пытаюсь построить оператор, который печатает список,
Почему ostream << * не компилируется? </p>

void operator<<(ostream& os, list<class T> &lst)
{
     list<T>::iterator it;
     for(it = lst.begin(); it!=lst.end(); it++)
     {
                  os<<*it<<endl; //This row
     }
}

Ответы [ 4 ]

3 голосов
/ 09 октября 2011

Потому что *it не реализует вставку потока. То есть, для operator<< нет перегрузки, которая принимает ostream и T. Обратите внимание, что вы должны возвращать ostream& os, чтобы разрешить цепочку операторов. Также ваше определение шаблона функции выглядит неправильно. Попробуйте сделать это вместо этого:

template< typename T >
ostream& operator<<(ostream& os, list<T> const& lst)
{
    std::copy(
        lst.begin(), lst.end()
      , std::ostream_iterator< T >( os )
    );
    return os;
}

или, что еще лучше, для поддержки потоков по всем видам элементов и признаков:

template< typename Elem, typename Traits, typename T >
std::basic_ostream< Elem, Traits >& operator<<(
    std::basic_ostream< Elem, Traits >& os
  , std::list<T> const& lst
)
{
    std::copy(
        lst.begin(), lst.end()
      , std::ostream_iterator< T >( os )
    );
    return os;
}

Кстати, вы можете передать разделитель конструктору std::ostream_iterator для вставки между каждым элементом.

* Обновление: * Я просто заметил, что даже если ваше объявление шаблона функции было правильным, вы будете иметь дело с зависимым типом. Итератор зависит от типа T, поэтому вам нужно сообщить об этом компилятору:

typename list<T>::iterator it;
1 голос
/ 09 октября 2011

Вы используете синтаксис шаблона неправильно:

template<class T>
void operator<<(ostream& os, list<T> &lst)
{
    list<T>::iterator it;
    for(it = lst.begin(); it!=lst.end(); it++)
    {
        os<<*it<<endl; //This row
    }
}

И, кстати, вы должны вернуть ссылку на поток, чтобы разрешить цепочку операторов вывода, и список должен быть константным, и вытакже можно использовать стандартную библиотеку для выполнения цикла вывода:

template<class T>
std::ostream& operator<<(std::ostream& os, const std::list<T> &lst)
{
    std::copy(lst.begin(), lst.end(), std::ostream_iterator<T>(os, "\n"));
    return os;
}
1 голос
/ 09 октября 2011

Я думаю, что проблема в декларации вашего шаблона. Следующее должно скомпилироваться и работать нормально:

template <typename T>
void operator<<(ostream& os, list<typename T> &lst)
{
      list<T>::iterator it;
      for(it = lst.begin(); it!=lst.end(); it++)
      {
                  os<<*it<<endl;
      }
}

Это, конечно, при условии, что тип элемента вашего списка может фактически использоваться с оператором << для ostream.

0 голосов
/ 11 октября 2011

Переписать на:

template<class T>
ostream& operator<<(ostream& os, list<T>& lst){
    typename list<T>::iterator it;
    for(it = lst.begin(); it != lst.end(); ++it){
                 os << *it << endl;
    }
    return os;
}
...