By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,409 Members | 1,139 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,409 IT Pros & Developers. It's quick & easy.

Why isn't the operator<< found?

P: n/a
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<char>,
ptrdiff_t>*)this)->std::istream_iterator<float_pair, char,
std::char_traits<char>, ptrdiff_t>::_M_stream >>
((std::istream_iterator<float_pair, char, std::char_traits<char>,
ptrdiff_t>*)this)->std::istream_iterator<float_pair, char,
std::char_traits<char>, ptrdiff_t>::_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>]

Jul 28 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
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:

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

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 <fstream>
#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
Jul 28 '05 #2

P: n/a
Ian
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:

#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> ()));
}

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

Ian
Jul 28 '05 #3

P: n/a
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:

#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)
Shouldn't this line be:
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<<?


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

Manfred
Jul 28 '05 #4

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

Manfred
Jul 28 '05 #5

P: n/a

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>>.

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.

Jul 28 '05 #6

P: n/a
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.

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

Jul 28 '05 #7

P: n/a
lutorm wrote:
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.
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
Jul 28 '05 #8

P: n/a
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>{};
--
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
Jul 28 '05 #9

P: n/a
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.

Jul 28 '05 #10

P: n/a
Ian
Maxim Yegorushkin 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:
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
Jul 28 '05 #11

P: n/a
[]
Are you sure?
Yes, I am.
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.

Jul 28 '05 #12

P: n/a


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<float, float> >, which I'm compelled to pass
later on.

Jul 28 '05 #13

P: n/a
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:

#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


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
Jul 29 '05 #14

P: n/a
lutorm wrote:
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<float, float> >, 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<float, float> > q(p.begin(), p.end());
}

Jul 29 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.