C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Why isn't the operator<< found?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
lutorm
Guest





PostPosted: Thu Jul 28, 2005 6:23 am    Post subject: Why isn't the operator<< found? Reply with quote



Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:

#include <fstream>
#include <vector>
#include <iterator>

using namespace std;

typedef std::pair<double, double> float_pair;

std::istream& operator>> (std::istream& s,
std::pair<double, double>& p)
{
s >> p.first;
s >> p.second;
return s;
}

main(){
ifstream file ("filename");

float_pair p;
file >> p; // this works

std::vector<float_pair> positions // but this doesn't
(istream_iterator<float_pair> (file),
(istream_iterator<float_pair> ()));
}

This used to work under my old compiler (KCC) but GCC 4.0 says it can't
find the operator<< (I think...) The full error message is below.
However, the operator works because when I try to read an individual
pair it works. Is there some magic that needs to be performed for the
istream_iterator to find the operator<
Thanks,

/Patrik Jonsson


[patrik@governator src]$ g++ optest.cc
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/bits/stream_iterator.h:
In member function 'void std::istream_iterator<_Tp, _CharT, _Traits,
_Dist>::_M_read() [with _Tp = float_pair, _CharT = char, _Traits =
std::char_traits<char>, _Dist = ptrdiff_t]':
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/bits/stream_iterator.h:68:
instantiated from 'std::istream_iterator<_Tp, _CharT, _Traits,
_Dist>::istream_iterator(std::basic_istream<_CharT, _Traits>&) [with
_Tp = float_pair, _CharT = char, _Traits = std::char_traits<char>,
_Dist = ptrdiff_t]'
optest.cc:24: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/bits/stream_iterator.h:119:
error: no match for 'operator>>' in
'*((std::istream_iterator<float_pair, char, std::char_traits ptrdiff_t>*)this)->std::istream_iterator<float_pair, char,
std::char_traits::_M_stream >>
((std::istream_iterator<float_pair, char, std::char_traits ptrdiff_t>*)this)->std::istream_iterator<float_pair, char,
std::char_traits::_M_value'
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:131:
note: candidates are: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT,
_Traits>::operator>>(std::basic_istream<_CharT, _Traits>&
(*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits
= std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:134:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(std::basic_ios<_CharT,
_Traits>& (*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char,
_Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:137:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(std::ios_base&
(*)(std::ios_base&)) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:169:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(bool&) [with _CharT =
char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:172:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(short int&) [with
_CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:175:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(short unsigned int&)
[with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:178:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(int&) [with _CharT =
char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:181:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(unsigned int&) [with
_CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:184:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(long int&) [with _CharT
= char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:187:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(long unsigned int&)
[with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:191:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(long long int&) [with
_CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:194:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(long long unsigned
int&) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:198:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(float&) [with _CharT =
char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:201:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(double&) [with _CharT =
char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:204:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(long double&) [with
_CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:207:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT, _Traits>::operator>>(void*&) [with _CharT =
char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:230:
note: std::basic_istream<_CharT, _Traits>&
std::basic_istream<_CharT,
_Traits>::operator>>(std::basic_streambuf<_CharT, _Traits>*) [with
_CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:688:
note: std::basic_istream<char, _Traits>&
std::operator>>(std::basic_istream<char, _Traits>&, unsigned char&)
[with _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:693:
note: std::basic_istream<char, _Traits>&
std::operator>>(std::basic_istream<char, _Traits>&, signed char&) [with
_Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:729:
note: std::basic_istream<char, _Traits>&
std::operator>>(std::basic_istream<char, _Traits>&, unsigned char*)
[with _Traits = std::char_traits<char>]
/usr/lib/gcc/x86_64-redhat-linux/4.0.0/../../../../include/c++/4.0.0/istream:734:
note: std::basic_istream<char, _Traits>&
std::operator>>(std::basic_istream<char, _Traits>&, signed char*) [with
_Traits = std::char_traits<char>]

Back to top
Steven T. Hatton
Guest





PostPosted: Thu Jul 28, 2005 6:55 am    Post subject: Re: Why isn't the operator<< found? Reply with quote



lutorm wrote:

Quote:
Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:

#include <fstream
#include #include ....

I don't know if you copied the code incorrectly, or the code you intended to

post had a parenthesis in the wrong place. Note that I used both GCC 3.3.5
and GCC 4.0.1. You may want to get the latest minor version.

$cat main.cpp
#include #include <vector>
#include <iterator>
#include <istream>

using namespace std;

typedef std::pair<double, double> float_pair;

std::istream& operator>> (std::istream& s,
std::pair<double, double>& p)
{
s >> p.first;
s >> p.second;
return s;
}

main(){
ifstream file ("filename");

float_pair p;
file >> p; // this works

std::vector<float_pair> positions // but this doesn't
(istream_iterator<float_pair> (file),istream_iterator<float_pair> ());
}


$gcc --version
gcc (GCC) 4.0.1
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ -otest main.cpp
$
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell

Back to top
Ian
Guest





PostPosted: Thu Jul 28, 2005 7:11 am    Post subject: Re: Why isn't the operator<< found? Reply with quote



lutorm wrote:
Quote:
Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:

#include <fstream
#include #include
using namespace std;

typedef std::pair
std::istream& operator>> (std::istream& s,
std::pair<double, double>& p)
{
s >> p.first;
s >> p.second;
return s;
}

main(){
ifstream file ("filename");

float_pair p;
file >> p; // this works

std::vector<float_pair> positions // but this doesn't
(istream_iterator<float_pair> (file),
(istream_iterator<float_pair> ()));
}

It's not << (must be all the template <) that can't be found, this

should compile OK.

Ian



Back to top
Manfred
Guest





PostPosted: Thu Jul 28, 2005 7:17 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

lutorm wrote:
Quote:
Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:

#include <fstream
#include #include
using namespace std;

typedef std::pair
std::istream& operator>> (std::istream& s,
std::pair<double, double>& p)

Shouldn't this line be:
std::istream& operator<< (std::istream& s, std::pair ^^^

Quote:
{
s >> p.first;
s >> p.second;
return s;
}

main(){
ifstream file ("filename");

float_pair p;
file >> p; // this works

std::vector<float_pair> positions // but this doesn't
(istream_iterator<float_pair> (file),
(istream_iterator<float_pair> ()));
}

This used to work under my old compiler (KCC) but GCC 4.0 says it can't
find the operator<< (I think...) The full error message is below.
However, the operator works because when I try to read an individual
pair it works. Is there some magic that needs to be performed for the
istream_iterator to find the operator<

You haven't defined operator<< (see above).

Manfred

Back to top
Manfred
Guest





PostPosted: Thu Jul 28, 2005 7:21 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

Please ignore my previous post.
Next time i'll think before i write :(

Manfred
Back to top
Maxim Yegorushkin
Guest





PostPosted: Thu Jul 28, 2005 7:45 am    Post subject: Re: Why isn't the operator<< found? Reply with quote


lutorm wrote:
Quote:
Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:
using namespace std;

typedef std::pair<double, double> float_pair;

std::istream& operator>> (std::istream& s,
std::pair<double, double>& p)
{
s >> p.first;
s >> p.second;
return s;
}

main(){
ifstream file ("filename");

float_pair p;
file >> p; // this works

std::vector<float_pair> positions // but this doesn't
(istream_iterator<float_pair> (file),
(istream_iterator<float_pair> ()));
}

This used to work under my old compiler (KCC) but GCC 4.0 says it can't
find the operator<< (I think...) The full error message is below.
However, the operator works because when I try to read an individual
pair it works. Is there some magic that needs to be performed for the
istream_iterator to find the operator<

The problem is that pair is declared in namespace std and the code for
istream_iterator as well the code for vector also are in namespace std.
istream_iterator uses operator>> for extraction. When it does this it
first searches for a most inner scope containing operator>>. The scope
happens to be namespace std, and none of the overloaded operator>>
declared there takes a pair. Second, it does an argument dependent name
lookup for operator>>. Since both of its arguments come from namespace
std the lookup never finds your global operator>>.

To workaround you may screw the standard and declare your operator>> in
namespace std. Be aware that this might lead to hard to track bugs if
some other smart guy does the same thing in one of the other
translation units your binary is comprised of.

The most portable solution is to use your own type instead of std::pair
and overload operator>> for it.


Back to top
lutorm
Guest





PostPosted: Thu Jul 28, 2005 8:18 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

Steven T. Hatton wrote:
Quote:
I don't know if you copied the code incorrectly, or the code you intended to
post had a parenthesis in the wrong place. Note that I used both GCC 3.3.5
and GCC 4.0.1. You may want to get the latest minor version.

No, it was copied correctly. The extra parentheses around one of the
istream_iterators are necessary because otherwise you don't create a
vector, you declare a function. Or at least so Item 6 (C++'s most
vexing parse) of Scott Myers' "Effective STL" says.

But after browsing a little more, I found the solution: The operator
apparently has to be declared in namespace std. I'm not sure why,
because I thought that lookup included the namespace of the caller, but
clearly I'm wrong. If anyone can offer an explanation of this, I'd be
all ears! :-)

/Patrik


Back to top
Steven T. Hatton
Guest





PostPosted: Thu Jul 28, 2005 8:36 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

lutorm wrote:

Quote:
Steven T. Hatton wrote:
I don't know if you copied the code incorrectly, or the code you intended
to post had a parenthesis in the wrong place. Note that I used both GCC
3.3.5
and GCC 4.0.1. You may want to get the latest minor version.

No, it was copied correctly. The extra parentheses around one of the
istream_iterators are necessary because otherwise you don't create a
vector, you declare a function. Or at least so Item 6 (C++'s most
vexing parse) of Scott Myers' "Effective STL" says.

Sorry. I realized that's what was going on after I sent the message. For
some strange reason only one of the parentheses was copied into the Emacs
buffer. (there's something broken in my beta version of KNode). When the
code didn't compile, I just removed the one parenthesis.

Quote:
But after browsing a little more, I found the solution: The operator
apparently has to be declared in namespace std. I'm not sure why,
because I thought that lookup included the namespace of the caller, but
clearly I'm wrong. If anyone can offer an explanation of this, I'd be
all ears! :-)

/Patrik

Can you provide the source where you found someone saying the operator needs
to be declared in namespace std, or are you talking about Maxim's post
here?
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell

Back to top
Steven T. Hatton
Guest





PostPosted: Thu Jul 28, 2005 8:59 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

lutorm wrote:

Quote:
Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:

What about this kludge?
struct float_pair: public pair<double, double>{};


--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell

Back to top
Maxim Yegorushkin
Guest





PostPosted: Thu Jul 28, 2005 9:46 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

Steven T. Hatton wrote:
Quote:
lutorm wrote:

Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:

What about this kludge?
struct float_pair: public pair<double, double>{};

You lose pair's constructors - all the functions it provides.


Back to top
Ian
Guest





PostPosted: Thu Jul 28, 2005 9:47 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

Maxim Yegorushkin wrote:
Quote:
lutorm wrote:

Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:
using namespace std;

typedef std::pair<double, double> float_pair;

std::istream& operator>> (std::istream& s,
std::pair<double, double>& p)
{
s >> p.first;
s >> p.second;
return s;
}

main(){
ifstream file ("filename");

float_pair p;
file >> p; // this works

std::vector<float_pair> positions // but this doesn't
(istream_iterator<float_pair> (file),
(istream_iterator<float_pair> ()));
}

This used to work under my old compiler (KCC) but GCC 4.0 says it can't
find the operator<< (I think...) The full error message is below.
However, the operator works because when I try to read an individual
pair it works. Is there some magic that needs to be performed for the
istream_iterator to find the operator<

The problem is that pair is declared in namespace std and the code for
istream_iterator as well the code for vector also are in namespace std.
istream_iterator uses operator>> for extraction. When it does this it
first searches for a most inner scope containing operator>>. The scope
happens to be namespace std, and none of the overloaded operator
declared there takes a pair. Second, it does an argument dependent name
lookup for operator>>. Since both of its arguments come from namespace
std the lookup never finds your global operator>>.

Are you sure? Even when all the types are fully qualified as in this

example?

Ian

Back to top
Maxim Yegorushkin
Guest





PostPosted: Thu Jul 28, 2005 10:45 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

[]

Quote:
Are you sure?

Yes, I am.

Quote:
Even when all the types are fully qualified as in this example?

file >> p; // this works

The call here works because it finds operator>> using ordinary lookup
because this is no template code. The set of viable functions for call
is comprised of the global operator>> and those found by ADL. The
latter set is empty.

istream_iterator<float_pair> does not work because it's a template, so
it searches for an operator>> in the second phase of name lookup using
ADL only, because the call is argument dependent. Since the operator>>
is not in the same namespace as any of its arguments, it can never be
found by ADL.


Back to top
lutorm
Guest





PostPosted: Thu Jul 28, 2005 7:04 pm    Post subject: Re: Why isn't the operator<< found? Reply with quote



Maxim Yegorushkin wrote:
Quote:
Steven T. Hatton wrote:
lutorm wrote:

Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:

What about this kludge?
struct float_pair: public pair<double, double>{};

You lose pair's constructors - all the functions it provides.

Even more significantly for me, vector<float_pair> is then not
convertible to vector<pair, which I'm compelled to pass
later on.


Back to top
Steven T. Hatton
Guest





PostPosted: Fri Jul 29, 2005 3:05 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

lutorm wrote:

Quote:
Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:

#include <fstream
#include #include
using namespace std;

typedef std::pair
std::istream& operator>> (std::istream& s,
std::pair<double, double>& p)
{
s >> p.first;
s >> p.second;
return s;
}

main(){
ifstream file ("filename");

float_pair p;
file >> p; // this works

std::vector<float_pair> positions // but this doesn't
(istream_iterator<float_pair> (file),
(istream_iterator<float_pair> ()));
}

This used to work under my old compiler (KCC) but GCC 4.0 says it can't
find the operator<< (I think...) The full error message is below.
However, the operator works because when I try to read an individual
pair it works. Is there some magic that needs to be performed for the
istream_iterator to find the operator<
Thanks,

/Patrik Jonsson


I haven't been able to make anything work, but I've been trying to create a
wrapper similar to an I/O manipulator that would serve no other real
function in life other than to bring the namespace into scope. I wonder if
someone else can find a way to accomplish that.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell

Back to top
Maxim Yegorushkin
Guest





PostPosted: Fri Jul 29, 2005 7:28 am    Post subject: Re: Why isn't the operator<< found? Reply with quote

lutorm wrote:
Quote:
Maxim Yegorushkin wrote:
Steven T. Hatton wrote:
lutorm wrote:

Hi everyone,
I'm trying to use istream_iterators to read a file consisting of pairs
of numbers. To do this, I wrote the following:

What about this kludge?
struct float_pair: public pair<double, double>{};

You lose pair's constructors - all the functions it provides.

Even more significantly for me, vector<float_pair> is then not
convertible to vector<pair, which I'm compelled to pass
later on.

You can still make it convertible, though it makes you copy:

#include <vector>
#include <algorithm>

struct S
{
float a, b;
operator std::pair<float, float>() const { return std::make_pair(a,
b); }
};

int main()
{
using namespace std;
vector<S> p;
vector<pair q(p.begin(), p.end());
}


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.