473,405 Members | 2,310 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

copy map to ostream_iterator

std::copy to std::ostream_iterator doesn't seem to
work with maps and pairs.

Shouldn't I expect something like this to work?

The G++ error message when USE_COPY_TO_PRINT is
defined as a non-zero number follows.

---------------- error message --------------------

<snip lower 'instantiated from' template chain>

constCorrectness.cpp:99: instantiated from here
/usr/include/c++/3.3.1/bits/stream_iterator.h:141: e
rror: no match for
'operator<<' in '*this->std::ostream_iterator<Pair
II, char,
std::char_traits<char> >::_M_stream << __value'
<snip candidate templates list>

-------------------- environment -------------------

Windows 2K, CygWin, g++

--------------------- makefile ---------------------

#!/usr/bin make

printmaps.exe : \
printmaps.o
printmaps.o : \
printmaps.cpp

%.exe : %.o
g++ -g -pedantic -Os -fexceptions -o $@ $^
%.o : %.cpp
g++ -g -pedantic -Os -fexceptions -o $@ -c $<
# EOF

------------------- compiler -----------------------
cmd /c g++ --version

g++ (GCC) 3.3.1 (cygming special)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying co
nditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FO
R A PARTICULAR PURPOSE.

------------------- source code --------------------
#include <map>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <sstream>

// -------------------------------------------------
// PROBLEM NOTE:
// Everything compiles with USE_COPY_TO_PRINT
// set to 0. Set to 1 to show the problem.
// -------------------------------------------------

#define USE_COPY_TO_PRINT 1

typedef std::pair<int ,int> PairII;

std::string
to_s(PairII const & pii) {
std::stringstream ss;
ss << "(" << pii.first << ","
<< pii.second << ")";
return ss.str();
}

std::ostream &
operator << (
std::ostream & os,
PairII const & pii) {
os << to_s(pii);
return os;
}

#if !USE_COPY_TO_PRINT

// -------------------------------------------------
// PROBLEM NOTE:
// This is a helper for the work-around.
// -------------------------------------------------

void
print(PairII const & pii) {
std::cout << to_s(pii) << "\n";
}

#endif

int main() {
size_t const N(5);
PairII a[N] = {
PairII(1,2),
PairII(3,4),
PairII(5,6),
PairII(7,8),
PairII(9,10)
};
std::map<int,int> m(
a,
a + N
);
std::cout << a[0] << "\n";
std::cout << *m.begin() << "\n";

#if USE_COPY_TO_PRINT

// -------------------------------------------------
// PROBLEM NOTE:
// This is the part that doesn't work.
// -------------------------------------------------

std::copy(
a,
a + N,
std::ostream_iterator<PairII>(
std::cout,
"\n"
)
);
std::copy(
m.begin(),
m.end(),
std::ostream_iterator<PairII>(
std::cout,
"\n"
)
);

#else

// -------------------------------------------------
// PROBLEM NOTE:
// This is the work around.
// -------------------------------------------------

std::for_each(
a,
a + N,
print
);
std::for_each(
m.begin(),
m.end(),
print
);

#endif

}
// EOF
--
Jeff

Vote Constitution Party! --Jeff
Jul 22 '05 #1
8 4591

"Jeff" <je******************@hotmail.com> wrote in message
news:1n*****************************@40tude.net...
std::copy to std::ostream_iterator doesn't seem to
work with maps and pairs.

Shouldn't I expect something like this to work?


Well perhaps. But there is no insertion operator defined for pairs by the
C++ standard, and surprisingly there is no useful way to define one.

This does not work

template <class T, class U>
ostream& operator<<(ostream& out, std::pair<T, U> const& p)
{
...
}

because the compiler will not look in the global namespace when trying to
find an operator<< for std::ostream and std::pair. The only namespace it
will look at is the std namespace, so this might work

namespace std
{
template <class T, class U>
ostream& operator<<(ostream& out, std::pair<T, U> const& p)
{
...
}
}

but it is not legal C++ because it is not legal to add definitions to the
std namespace.

In my view this is a defect in the C++ language.

john
Jul 22 '05 #2

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2s*************@uni-berlin.de...

"Jeff" <je******************@hotmail.com> wrote in message
news:1n*****************************@40tude.net...
std::copy to std::ostream_iterator doesn't seem to
work with maps and pairs.

Shouldn't I expect something like this to work?


Well perhaps. But there is no insertion operator defined for pairs by the
C++ standard, and surprisingly there is no useful way to define one.

This does not work

template <class T, class U>
ostream& operator<<(ostream& out, std::pair<T, U> const& p)
{
...
}

because the compiler will not look in the global namespace when trying to
find an operator<< for std::ostream and std::pair.


I should add that this is only because the compiler is looking for
operator<< from within std::copy which obviously is in the std namespace. If
you wrote your own version of std::copy in the global namespace, then I
believe it would work.

john
Jul 22 '05 #3
>
I should add that this is only because the compiler is looking for
operator<< from within std::copy


That of course is complete nonsense. operator << is being accessed from
inside std::ostream_iterator, which again is in the std namespace, but a bit
harder to rewrite than std::copy.

john
Jul 22 '05 #4
Jeff <je******************@hotmail.com> wrote in message news:<1n*****************************@40tude.net>. ..
std::copy to std::ostream_iterator doesn't seem to
work with maps and pairs.

Shouldn't I expect something like this to work?


<snipalot/>

No, actually not. std::copy is in std, std::ostream is in std and
std::pair is in std, thus there's no reason why it should look outside
std for a <<. I don't quite understand why it won't let you define the
operator in std though.

For what it's worth, a better workaround than the one you have would
use transform:

std::transform(themap.begin(), themap.end(),
std::ostream_iterator<std::string>(cout, "\n"), to_s);
Jul 22 '05 #5
On Sat, 2 Oct 2004 10:28:40 +0100, John Harrison wrote:
namespace std
{
template <class T, class U>
ostream& operator<<(ostream& out, std::pair<T, U> const& p)
{
...
}
}


Thanks for your help. That works, but I decided to go with transform so I
don't have to inject into 'std' or rewrite the ostream_iterator outside of
std.
--
Jeff

Vote Constitution Party! --Jeff
Jul 22 '05 #6
On 2 Oct 2004 07:44:58 -0700, CornedBee wrote:
std::transform(themap.begin(), themap.end(),
std::ostream_iterator<std::string>(cout, "\n"), to_s);


Thanks. This works well.

The standard library has failed the least-surprises design criteria on this
point, hasn't it? Shouldn't the designers of pair have included stream
support for it? Maybe not, if they'd have to guess how you want to
represent formatted pairs. There may be lots of options like

(1,2)
1=2
1:2

and so on.
--
Jeff

Vote Constitution Party! --Jeff
Jul 22 '05 #7
"John Harrison" <jo*************@hotmail.com> wrote in message news:<2s*************@uni-berlin.de>...

[ ... ]
this might work

namespace std
{
template <class T, class U>
ostream& operator<<(ostream& out, std::pair<T, U> const& p)
{
...
}
}

but it is not legal C++ because it is not legal to add definitions to the
std namespace.


If you look carefully, you'll find that there are circumstances under
which it IS legal to add definitions to the std namespace -- and
unless memory serves me particularly ill tonight, this would fit
within the rules.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 22 '05 #8

"Jerry Coffin" <jc*****@taeus.com> wrote in message
news:b2*************************@posting.google.co m...
"John Harrison" <jo*************@hotmail.com> wrote in message
news:<2s*************@uni-berlin.de>...

[ ... ]
this might work

namespace std
{
template <class T, class U>
ostream& operator<<(ostream& out, std::pair<T, U> const& p)
{
...
}
}

but it is not legal C++ because it is not legal to add definitions to the
std namespace.


If you look carefully, you'll find that there are circumstances under
which it IS legal to add definitions to the std namespace -- and
unless memory serves me particularly ill tonight, this would fit
within the rules.


I think your memory serves you ill. This is covered in 17.4.3.1. The only
exception is for specializations of existing templates. Additional function
overloads (templates or not) are not allowed.

john
Jul 22 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Thomas J. Clancy | last post by:
I was wondering if anyone knew of a way to use std::copy() and istream_iterator<>/ostream_iterator<> write a file copy function that is quick and efficient. Doing this messes up the file because...
2
by: Severin Ecker | last post by:
hi! i'm trying to copy a file with the std::copy function but my problem is, that whitespaces are discarded. could anyone tell me how i can just copy all the characters that are in the...
6
by: ma740988 | last post by:
There's no way to use the STL algorithm copy to print an outfile (essentially an ofstream)? So now: int main() { std::ifstream InFile( "exercise15.txt"); std::ofstream ToFile( "NewFile.txt"...
1
by: utab | last post by:
#include <iostream> #include <vector> #include <string> #include <algorithm> #include <iterator> using std::cout; using std::vector; using std::string; using std::endl;
1
by: Siegfried Heintze | last post by:
What is the minimum I must type to create a custom iterator that will allow me display my iterator on std::cout using std::copy? Thanks, Siegfried
9
by: Paulo Matos | last post by:
Hi all, Given a list of int, it's rather easy to output them line by line: std::copy(mylist.begin(), mylist.end(), std::ostream_iterator<int>(cout, "\n"); Now, there's two ways in which I...
5
by: Fred | last post by:
Hi: I've got the following request: (suppose the required head file is included) vector<stringvec; // .......... // push some items into vec string str; // here I want to copy some range...
2
by: Scofield | last post by:
copy (coll.begin(), coll.end(), ostream_iterator<int>(cout, " ")); when compile, it yields the following errors: list1.cpp:12: error: ¡®ostream_iterator¡¯ was not declared in this scope...
20
by: Adalte | last post by:
Hi ! When I compile this piece of code I get the following error: "NewShapes.cpp: In function `int main()': NewShapes.cpp:12: error: `ShapePtr' cannot appear in a constant-expression...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.