473,803 Members | 3,428 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Stream operator in namespace masks global stream operator

Hi folks. I've got a weird situation--gcc doesn't like the folllowing
code snippet, but I don't know if it's correct or not. Here's the
situation:

In the global namespace, I've got a operator<< declared that will send
a vector<Tto a std::ostream.
In the "outer" namespace, I've got a operator<< declared that will
send a Thing<Tto a std::ostream.
In the "outer" namespace, I've got a function "foo" that tries to send
a vector<Tto a std::ostream.

When I try to compile it, gcc complains that there's no match for
operator<< in the foo function's definition.

Is this correct? Why is gcc not seeing the global namespace
operator<< ?

Thanks,
--Steve (sg****@sjm.com )

=== test.cpp ===

#include <iostream>
#include <vector>

template<typena me Tstd::ostream & operator<< (std::ostream & o,
const std::vector<T& v);

namespace outer {

template<class Tclass Thing { };

template<typena me Tstd::ostream & operator<< (std::ostream & o,
const Thing<T& t);

void foo() { std::vector<dou blev; std::cout << v; }

}

int main()
{
return 0;
}

=== EOF ===

May 9 '07 #1
3 2623
mrstephengross wrote:
Hi folks. I've got a weird situation--gcc doesn't like the folllowing
code snippet, but I don't know if it's correct or not. Here's the
situation:

In the global namespace, I've got a operator<< declared that will send
a vector<Tto a std::ostream.
In the "outer" namespace, I've got a operator<< declared that will
send a Thing<Tto a std::ostream.
In the "outer" namespace, I've got a function "foo" that tries to send
a vector<Tto a std::ostream.

When I try to compile it, gcc complains that there's no match for
operator<< in the foo function's definition.

Is this correct? Why is gcc not seeing the global namespace
operator<< ?

Thanks,
--Steve (sg****@sjm.com )

=== test.cpp ===

#include <iostream>
#include <vector>

template<typena me Tstd::ostream & operator<< (std::ostream & o,
const std::vector<T& v);

namespace outer {

template<class Tclass Thing { };

template<typena me Tstd::ostream & operator<< (std::ostream & o,
const Thing<T& t);

void foo() { std::vector<dou blev; std::cout << v; }

}

int main()
{
return 0;
}

=== EOF ===
The compiler is telling you it cannot find a prototype for '<<' in foo.
The '<<' function hides the '<<' function in global namespace. Try the
below implementation instead:

#include <iostream>
#include <vector>

template<typena me Tstd::ostream & operator<< (std::ostream & o,
const std::vector<T& v);

namespace outer {

template<class Tclass Thing { };

template<typena me Tstd::ostream & operator<< (std::ostream & o,
const T & t);

void foo() { std::vector<dou blev; std::cout << v; }

}

int main()
{
return 0;
}
May 9 '07 #2
I think compiling is ok but linking has an error with symbol not
found.

Just in case if you used gcc, it'd be g++.

cheers

On May 9, 10:37 am, mrstephengross <mrstephengr... @hotmail.comwro te:
Hi folks. I've got a weird situation--gcc doesn't like the folllowing
code snippet, but I don't know if it's correct or not. Here's the
situation:

In the global namespace, I've got a operator<< declared that will send
a vector<Tto a std::ostream.
In the "outer" namespace, I've got a operator<< declared that will
send a Thing<Tto a std::ostream.
In the "outer" namespace, I've got a function "foo" that tries to send
a vector<Tto a std::ostream.

When I try to compile it, gcc complains that there's no match for
operator<< in the foo function's definition.

Is this correct? Why is gcc not seeing the global namespace
operator<< ?

Thanks,
--Steve (sgr...@sjm.com )

=== test.cpp ===

#include <iostream>
#include <vector>

template<typena me Tstd::ostream & operator<< (std::ostream & o,
const std::vector<T& v);

namespace outer {

template<class Tclass Thing { };

template<typena me Tstd::ostream & operator<< (std::ostream & o,
const Thing<T& t);

void foo() { std::vector<dou blev; std::cout << v; }

}

int main()
{
return 0;

}

=== EOF ===

May 9 '07 #3
On May 9, 4:37 pm, mrstephengross <mrstephengr... @hotmail.comwro te:
Hi folks. I've got a weird situation--gcc doesn't like the folllowing
code snippet, but I don't know if it's correct or not. Here's the
situation:
In the global namespace, I've got a operator<< declared that will send
a vector<Tto a std::ostream.
Note that you cannot do this reliably. In order for the
compiler to reliably find the operator, including in template
code where it occurs in a dependent context, it must be able to
find it using ADL. Which means that the operator must be in std
(or the namespace in which T is defined---built-in types are in
no namespace, however). And you cannot, legally, add things
like this to std.
In the "outer" namespace, I've got a operator<< declared that will
send a Thing<Tto a std::ostream.
In the "outer" namespace, I've got a function "foo" that tries to send
a vector<Tto a std::ostream.
When I try to compile it, gcc complains that there's no match for
operator<< in the foo function's definition.
Is this correct? Why is gcc not seeing the global namespace
operator<< ?
=== test.cpp ===
#include <iostream>
#include <vector>
template<typena me Tstd::ostream & operator<< (std::ostream & o,
const std::vector<T& v);
namespace outer {
template<class Tclass Thing { };
template<typena me Tstd::ostream & operator<< (std::ostream & o,
const Thing<T& t);
void foo() { std::vector<dou blev; std::cout << v; }
}
int main()
{

}
=== EOF ===
G++ is correct. Unqualified lookup stops when it finds the
name, here, in outer, and doesn't look further. That exposes
the operator<< in outer, and no other operator<<. ADL kicks in,
and causes lookup in the namespaces related to the arguments:
here, std, so the operator<< in std are also added to the
overload set. There's nothing to cause the compiler to look in
the global namespace, however. The built-in types are defined
in no namespace (and can't have any effect on ADL), and not in
the global namespace.

Faced with this problem, there are two answers, depending on
context:

-- In production code: don't do this. You never, never want to
overload << on something like std::vector<dou blein
production code. It will introduce subtle coupling, and
will cause problems in the long run. When you need to
output a vector, either write function to do it, or use the
decorator pattern to call operator<< on one of your types.

-- For quick tests, or playing around: it's formally undefined
behavior to define this operator in namespace std, but in
practice, it won't cause any problems, so just go ahead and
do it:-).

Note that both of the above solutions depend on ADL, and so will
also work from within a template.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 10 '07 #4

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

Similar topics

2
3522
by: Xavier Decoret | last post by:
The following code does not compoile with gcc-3.2.3 namespace dummy { //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Interface of Foo //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ class Foo { public:
7
2160
by: Martin Stich | last post by:
hi, i want to redefine the global operator new for logging and stats purposes. is it a good idea to use malloc() as allocation function ? or should i call one of those weird crt functions....or ask the OS directly? oh and another question: which parts of my program will actually use my version of new ? only the ones that include the declaration (do i even need one or is a definition in a cpp file ok?). what about statically linked...
4
1499
by: Glen Able | last post by:
I'd like to use a few different memory arenas in my current application and to be able to specify for each allocation where it comes from. Is there any way I can make operator new take another argument to specify which arena an object gets allocated from. Or fake it? e.g. I'd like to be able to write something like this: A* myA = new_bigheap A; A* otherA = new_fastheap A;
14
2342
by: lutorm | last post by:
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;
20
3873
by: Patrick Guio | last post by:
Dear all, I have some problem with insertion operator together with namespace. I have a header file foo.h containing declaration of classes, typedefs and insertion operators for the typedefs in a named namespace namespace foo { class Foo
9
2493
by: Javaman59 | last post by:
I saw in a recent post the :: operator used to reach the global namespace, as in global::MyNamespace I hadn't seen this before, so looked it up in MSDN, which explained it nicely. My question is, do "global" and "::" always go together? Is there any other use for these operators, than as a pair? TIA,
11
1936
by: bob | last post by:
Hi, given a vector of vectors of strings thus; typedef std::vector<std::string> product; typedef std::vector<product> product_matrix; whats the fastest, most efficient means of streaming the "product_matrix" to a file? I.E. without using two "for" or "while"
2
3197
by: ryan_melville | last post by:
Hi, Should I put the operator<<() for my class (which is in a namespace) in the namespace or make it global? If I understand the lookup rules correctly: If I make it global, it may be hidden if called from within a different namespace and that other namespace has any operator<<() defined. That doesn't seem good.
11
3825
by: jakester | last post by:
I am using Visual C++ 2007 to build the code below. I keep getting linkage error. Could someone please tell me what I am doing wrong? The code works until I start using namespace for my objects. Error 1 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char & __cdecl graph::operator<<(class std::basic_ostream<char,struct std::char_traits<char &,class graph::Node &)" (??6graph@@YAAAV?...
0
9700
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9564
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10546
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10310
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10292
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10068
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6841
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5627
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4275
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.