473,231 Members | 1,902 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,231 software developers and data experts.

How to resolve ADL(?) issue using std::copy and std::ostream_iterator

Greetings all. I am really stuck on this one as I can't seem to grok if
I am abusing the C++ language or if I am simply using components of the
C++ Standard Library incorrectly. Here is the code:

#include <string>
#include <map>
#include <iostream>
#include <utility>
#include <iterator>

typedef std::pair<std::string, std::stringSTR;

#ifdef NON_COMPLIANT
// Works but my understanding this is forbidden by
// Standard ISO/IEC 14882.2003 17.4.3.1-1
// since I introduce code into namespace std
namespace std {
{
std::ostream& operator<<(std::ostream& os, STR const& ip) {
os << ip.first << " " << ip.second << std::endl;
return os;
}
}
#else
// Generates error
// std::copy can't find a suitable candidate for operator<<
std::ostream& operator<<(std::ostream& os, STR const& ip) {
os << ip.first << " " << ip.second << std::endl;
return os;
}
#endif

int main(int argc, char** argv, char** env) {
std::map<std::string, std::stringtest;
test["foo"] = "bar";
test["baz"] = "qux";

std::ostream_iterator<STRo(std::cout);
std::copy(
test.begin(),
test.end(),
o);

return 0;
}

If compiled with the macro definition NON_COMPLIANT line 12 violates the
Standard section 17.4.3.1-1 commented on in the code but that seems to
be the only way to allow for std::copy to deduce the correct context of
operator<<, is this correct? (I apologize if I am not using the correct
terminology - please educate me accordingly on this as well)

If my understanding above is correct then can I conclude that I simply
do not understand how to use the Standard C++ library correctly in this
case? The code appears to be a logical use of the components at play
but my compiler disagrees with my thinking.

Thank you for reading and any insight you can assist me with in advance.
Chris
Jul 2 '06 #1
6 1937
* Chris Johnson:
Greetings all. I am really stuck on this one as I can't seem to grok if
I am abusing the C++ language or if I am simply using components of the
C++ Standard Library incorrectly. Here is the code:

#include <string>
#include <map>
#include <iostream>
#include <utility>
#include <iterator>

typedef std::pair<std::string, std::stringSTR;

#ifdef NON_COMPLIANT
// Works but my understanding this is forbidden by
// Standard ISO/IEC 14882.2003 17.4.3.1-1
// since I introduce code into namespace std
namespace std {
{
std::ostream& operator<<(std::ostream& os, STR const& ip) {
os << ip.first << " " << ip.second << std::endl;
return os;
}
}
#else
// Generates error
// std::copy can't find a suitable candidate for operator<<
std::ostream& operator<<(std::ostream& os, STR const& ip) {
os << ip.first << " " << ip.second << std::endl;
return os;
}
#endif

int main(int argc, char** argv, char** env) {
std::map<std::string, std::stringtest;
test["foo"] = "bar";
test["baz"] = "qux";

std::ostream_iterator<STRo(std::cout);
std::copy(
test.begin(),
test.end(),
o);

return 0;
}

If compiled with the macro definition NON_COMPLIANT line 12 violates the
Standard section 17.4.3.1-1 commented on in the code but that seems to
be the only way to allow for std::copy to deduce the correct context of
operator<<, is this correct? (I apologize if I am not using the correct
terminology - please educate me accordingly on this as well)
There are a number of related active issues at <url:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/lwg-toc.html>, but I'm not sure
whether this is one of them.

Related paper by Howard Hinnant: <url:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1387.htm>.

I think this question belongs in [comp.std.c++], and I suggest you post
the question there.

If my understanding above is correct then can I conclude that I simply
do not understand how to use the Standard C++ library correctly in this
case? The code appears to be a logical use of the components at play
but my compiler disagrees with my thinking.
I think you can conclude that /probably/ the standard is a bit defective
in this regard, there being a number of related active issues.

Thank you for reading and any insight you can assist me with in advance.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 2 '06 #2
In article <JbTpg.28904$FR1.15119@dukeread05>,
Chris Johnson <de*********@gmail.comwrote:
Greetings all. I am really stuck on this one as I can't seem to grok if
I am abusing the C++ language or if I am simply using components of the
C++ Standard Library incorrectly. Here is the code:

#include <string>
#include <map>
#include <iostream>
#include <utility>
#include <iterator>

typedef std::pair<std::string, std::stringSTR;

#ifdef NON_COMPLIANT
// Works but my understanding this is forbidden by
// Standard ISO/IEC 14882.2003 17.4.3.1-1
// since I introduce code into namespace std
namespace std {
{
std::ostream& operator<<(std::ostream& os, STR const& ip) {
os << ip.first << " " << ip.second << std::endl;
return os;
}
}
#else
// Generates error
// std::copy can't find a suitable candidate for operator<<
std::ostream& operator<<(std::ostream& os, STR const& ip) {
os << ip.first << " " << ip.second << std::endl;
return os;
}
#endif

int main(int argc, char** argv, char** env) {
std::map<std::string, std::stringtest;
test["foo"] = "bar";
test["baz"] = "qux";

std::ostream_iterator<STRo(std::cout);
std::copy(
test.begin(),
test.end(),
o);

return 0;
}

If compiled with the macro definition NON_COMPLIANT line 12 violates the
Standard section 17.4.3.1-1 commented on in the code but that seems to
be the only way to allow for std::copy to deduce the correct context of
operator<<, is this correct? (I apologize if I am not using the correct
terminology - please educate me accordingly on this as well)

If my understanding above is correct then can I conclude that I simply
do not understand how to use the Standard C++ library correctly in this
case? The code appears to be a logical use of the components at play
but my compiler disagrees with my thinking.

Thank you for reading and any insight you can assist me with in advance.
Chris
Your understanding is correct in on all counts. The standard is simply
deficient in this area. I had hoped that tuple I/O would save the day
here (pair simply being a special case of tuple length 2). However I/O
was stripped from the tuple library shortly before it was voted into
TR1. tuple is now in the C++0X working draft (still missing I/O). I am
hopeful that it can gain I/O in time for C++0X, but as yet there is no
such concrete proposal.

-Howard
Jul 2 '06 #3
* Howard Hinnant:
I had hoped that tuple I/O would save the day
here (pair simply being a special case of tuple length 2). However I/O
was stripped from the tuple library shortly before it was voted into
TR1. tuple is now in the C++0X working draft (still missing I/O). I am
hopeful that it can gain I/O in time for C++0X, but as yet there is no
such concrete proposal.
I think the problem here is both more general and fundamental: that it
should be valid (not UB) to overload at least some functions in the
'std' namespace, namely, those that serve as customization points.

Perhaps it is already valid, i.e. that somewhere the standard mentions
that it's OK to provide overloads of std::operator<< for user-defined
type (any such wording would be compatible with 17.4.3.1/1, which
refers to exceptions), but I failed to find that. Perhaps ADL "should"
find the user-defined ::operator<<, but at least with my preferred
compiler it didn't, and checking the details in the standard is
laborious work. So I'm assuming the OP's problem is real: ADL doesn't
find ::operator<<, and defining std::operator<< is Strictly Verboten.

Under that assumption: supporting tuple i/o is all well and good, but it
won't solve the OP's problem for some class that can't be expressed as a
tuple; only a more general solution can do that.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 2 '06 #4
In article <4g*************@individual.net>,
"Alf P. Steinbach" <al***@start.nowrote:
Under that assumption: supporting tuple i/o is all well and good, but it
won't solve the OP's problem for some class that can't be expressed as a
tuple; only a more general solution can do that.
The general problem is that the standard has a hole in it. It provides
I/O for all scalar types, and for several standard class types,
including:

basic_string
bitset
complex

But the standard is lacking I/O for several standard types, including:

pair
all of the containers (except string)

This isn't an ADL issue as there are no user-defined types in the OP's
problem. They're all standard types. Indeed, if there were a
user-defined type in the OP's problem, e.g.:

typedef std::pair<MyString, std::stringSTR;

then ADL would save the day.

We could possibly say that it is ok for users to add stuff into
namespace std that does not depend on user-defined types. But I think
eliminating the motivation for doing so by providing commonly needed
functionality (such as I/O) for standard types would be a superior
solution.

-Howard
Jul 2 '06 #5

"Howard Hinnant" <ho************@gmail.comskrev i meddelandet
news:ho**********************************@syrcnyrd rs-03-ge0.nyroc.rr.com...
In article <4g*************@individual.net>,
"Alf P. Steinbach" <al***@start.nowrote:
>Under that assumption: supporting tuple i/o is all well and good,
but it
won't solve the OP's problem for some class that can't be expressed
as a
tuple; only a more general solution can do that.

The general problem is that the standard has a hole in it. It
provides
I/O for all scalar types, and for several standard class types,
including:

basic_string
bitset
complex

But the standard is lacking I/O for several standard types,
including:

pair
all of the containers (except string)

This isn't an ADL issue as there are no user-defined types in the
OP's
problem. They're all standard types. Indeed, if there were a
user-defined type in the OP's problem, e.g.:

typedef std::pair<MyString, std::stringSTR;

then ADL would save the day.

We could possibly say that it is ok for users to add stuff into
namespace std that does not depend on user-defined types.
But how do we know exactly what overload are already provided?
But I think
eliminating the motivation for doing so by providing commonly needed
functionality (such as I/O) for standard types would be a superior
solution.
Right!
Bo Persson
Jul 2 '06 #6
Howard Hinnant wrote:
In article <4g*************@individual.net>,
"Alf P. Steinbach" <al***@start.nowrote:
--8<--[SNIP]--8<--
But the standard is lacking I/O for several standard types, including:

pair
all of the containers (except string)
I think I can say safely say that I now understand this where before
posting I did not.
This isn't an ADL issue as there are no user-defined types in the OP's
problem. They're all standard types. Indeed, if there were a
user-defined type in the OP's problem, e.g.:

typedef std::pair<MyString, std::stringSTR;

then ADL would save the day.
In fact, using a user defined type, it does. I now know what
(correctly) ADL is.

Thanks for the insight to all that have responded - I learned a few
things as a result. I can't thank everyone enough.

Chris
Jul 3 '06 #7

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

Similar topics

9
by: PerritoPerron | last post by:
Hi there fellas.. I am learning this powerful language, but came accross a concatenation problem that I can't resolve. I have 2 arrays A1 = {1,2,3,4}; A2 = {1,3,5,7}; I need to put them...
9
by: ES Kim | last post by:
#include <map> #include <iterator> #include <iostream> #include <algorithm> using namespace std; typedef map<int, int> Map; ostream& operator<<(ostream& os, const Map::value_type& v);
1
by: Siegfried Heintze | last post by:
Should the following work? It does on some compilers. How can I get it to work on g++ 3.2? On g++ 3.2 it keeps telling me that there is no such function operator << for ostream and...
6
by: Chris Roth | last post by:
I'm just starting out using the algorithms in c++ std library. I have a vector of vectors (v) and want to get a slice at some index. ex. If v held two vectors, v1 and v2: v1 = 1 2 3 4 5 6 v2 =...
5
by: krzysztof.konopko | last post by:
I cannot compile the code which defines a std::map type consisting of built in types and operator<< overload for std::map::value_type. See the code below - I attach a full example. Note: if I...
6
by: hsmit.home | last post by:
Hello, I came across a strange error and it's really been bugging me. Maybe someone else has come across this and any insight would be appreciated. What I'm trying to accomplish is using...
16
by: Juha Nieminen | last post by:
The so-called koenig lookup allows doing odd things like this: #include <algorithm> #include <string> int main() { std::string table; sort(table, table+10); }
9
by: arnuld | last post by:
Earlier, I have posted a program like this, a month ago IIRC. I have created it again, without looking at the old program. Can I have your opinions on this: 1) I wanted my program to be...
42
by: barcaroller | last post by:
In the boost::program_options tutorial, the author included the following code: cout << "Input files are: " << vm.as< vector<string() << "\n"; Basically, he is trying to print a vector...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...

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.