LINUX.ORG.RU

C++ STL: ostream_iterator


0

0

Привет!
Не получается скомпилировать следующую програмку:

#include <iostream>
#include <fstream>
#include <iterator>
#include <utility>

namespace std
{
template <typename T>
std::ostream& operator<<(std::ostream &out, std::pair<T, T> &p)
{
out << p.first << p.second;
return out;
}
}

// using namespace std;

int main(int argc, char** argv)
{
std::ofstream out_f_stream("out.dat");
std::ostream_iterator< std::pair<int, int> > out_begin(out_f_stream);
*out_begin = std::make_pair(1, 2);
out_begin++;
*out_begin = std::make_pair(2, 3);

return 0;
}

Говорит что нет оператора <<. Хотя я его определил.

Вот вывод об ошибке:


g++-3.3 test02.cc
/usr/include/c++/3.3/bits/stream_iterator.h: In member function `
std::ostream_iterator<_Tp, _CharT, _Traits>& std::ostream_iterator<_Tp,
_CharT, _Traits>::operator=(const _Tp&) [with _Tp = std::pair<int, int>,
_CharT = char, _Traits = std::char_traits<char>]':
test02.cc:22: instantiated from here
/usr/include/c++/3.3/bits/stream_iterator.h:141: error: no match for 'operator
<<' in '*this->std::ostream_iterator<std::pair<int, int>, char,
std::char_traits<char> >::_M_stream << __value'
/usr/include/c++/3.3/bits/ostream.tcc:63: error: candidates are:
std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
_Traits>::operator<<(std::basic_ostream<_CharT,
_Traits>&(*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char,
_Traits = std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:74: error:
std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
_Traits>::operator<<(std::basic_ios<_CharT,
_Traits>&(*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits
= std::char_traits<char>]



итд...итд...

anonymous

Ответ на: комментарий от sf

Согласен :) Поверешь, нет, но такой пример приведен в одной из книжек С++ in Depth. Только там istream_iterator. Я же, хотел аналогично сделать для ostream_iterator, но что-то не получается :(

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

ну пример работать врядли будет, т.к. неконстантная ссылка на пару передается в <<, а создается, похоже, временный объект (через make_pair). Как минимум надо дорисовать const :]

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

Я тут немного порылся (кусок bits/stream_iterator.h):
/// Writes @a value to underlying ostream using operator<<.  If
/// constructed with delimiter string, writes delimiter to  
/// ostream.
ostream_iterator&
operator=(const _Tp& __value)
{
   __glibcxx_requires_cond(_M_stream != 0,
            _M_message(__gnu_debug::__msg_output_ostream)
             ._M_iterator(*this));

   *_M_stream << __value;
   //        ^^^
   //        |||

   if (_M_string) *_M_stream << _M_string;
   return *this;
}

То есть действительно оператор будет искаться в std::.

итого имеем :

--- main.cc     2006-11-07 12:32:31.000000000 +0200
+++ main.cc.orig        2006-11-07 12:32:19.000000000 +0200
@@ -6,7 +6,7 @@
 namespace std
 {
 template <typename T>
-std::ostream& operator<<(std::ostream &out,const std::pair<T, T> &p)
+std::ostream& operator<<(std::ostream &out, std::pair<T, T> &p)
 {
 out << p.first << p.second;
 return out;

С сиим патчем работает :].

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

сорри неправильно diffнул.

--- main.cc.orig        2006-11-07 12:32:19.000000000 +0200
+++ main.cc     2006-11-07 12:32:31.000000000 +0200
@@ -6,7 +6,7 @@
 namespace std
 {
 template <typename T>
-std::ostream& operator<<(std::ostream &out, std::pair<T, T> &p)
+std::ostream& operator<<(std::ostream &out,const std::pair<T, T> &p)
 {
 out << p.first << p.second;
 return out;

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

sf! СПАСИБО! А что ты хотел сказать этим: "То есть действительно оператор будет искаться в std::." ???

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

Ну если оператор описать не в этом пространстве то его видно не будет. Будет скрываться всякими std::basic_ostream<_CharT, _Traits>::operator<<(long int) std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) std::basic_ostream<_CharT, _Traits>::operator<<(bool) и т.д. (ну то, что он в ошибках вываливает).

Лучше итераторами для такого изврата не пользоваться, а вызывать явно out_f_stream << p; Чтобы инстанцирование происходило в том пространстве имён, где определен твой operator << а не в каких-то там std::ostream_operator::operator=(... :]

sf ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.