 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
lutorm Guest
|
Posted: Thu Jul 28, 2005 6:23 am Post subject: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 6:55 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 7:11 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 7:17 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 7:21 am Post subject: Re: Why isn't the operator<< found? |
|
|
Please ignore my previous post.
Next time i'll think before i write :(
Manfred
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Thu Jul 28, 2005 7:45 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 8:18 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 8:36 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 8:59 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 9:46 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 9:47 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Thu Jul 28, 2005 10:45 am Post subject: Re: Why isn't the operator<< found? |
|
|
[]
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
|
Posted: Thu Jul 28, 2005 7:04 pm Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Fri Jul 29, 2005 3:05 am Post subject: Re: Why isn't the operator<< found? |
|
|
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
|
Posted: Fri Jul 29, 2005 7:28 am Post subject: Re: Why isn't the operator<< found? |
|
|
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 |
|
 |
|
|
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
|
|