Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Stream operator in namespace masks global stream operator

Reply
Thread Tools

Stream operator in namespace masks global stream operator

 
 
mrstephengross
Guest
Posts: n/a
 
      05-09-2007
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<T> to a std:stream.
In the "outer" namespace, I've got a operator<< declared that will
send a Thing<T> to a std:stream.
In the "outer" namespace, I've got a function "foo" that tries to send
a vector<T> to a std:stream.

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 ()

=== test.cpp ===

#include <iostream>
#include <vector>

template<typename T> std:stream & operator<< (std:stream & o,
const std::vector<T> & v);

namespace outer {

template<class T> class Thing { };

template<typename T> std:stream & operator<< (std:stream & o,
const Thing<T> & t);

void foo() { std::vector<double> v; std::cout << v; }

}

int main()
{
return 0;
}

=== EOF ===

 
Reply With Quote
 
 
 
 
Fei Liu
Guest
Posts: n/a
 
      05-09-2007
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<T> to a std:stream.
> In the "outer" namespace, I've got a operator<< declared that will
> send a Thing<T> to a std:stream.
> In the "outer" namespace, I've got a function "foo" that tries to send
> a vector<T> to a std:stream.
>
> 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 ()
>
> === test.cpp ===
>
> #include <iostream>
> #include <vector>
>
> template<typename T> std:stream & operator<< (std:stream & o,
> const std::vector<T> & v);
>
> namespace outer {
>
> template<class T> class Thing { };
>
> template<typename T> std:stream & operator<< (std:stream & o,
> const Thing<T> & t);
>
> void foo() { std::vector<double> v; 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<typename T> std:stream & operator<< (std:stream & o,
const std::vector<T> & v);

namespace outer {

template<class T> class Thing { };

template<typename T> std:stream & operator<< (std:stream & o,
const T & t);

void foo() { std::vector<double> v; std::cout << v; }

}

int main()
{
return 0;
}
 
Reply With Quote
 
 
 
 
modemer
Guest
Posts: n/a
 
      05-09-2007
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.com> 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<T> to a std:stream.
> In the "outer" namespace, I've got a operator<< declared that will
> send a Thing<T> to a std:stream.
> In the "outer" namespace, I've got a function "foo" that tries to send
> a vector<T> to a std:stream.
>
> 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<typename T> std:stream & operator<< (std:stream & o,
> const std::vector<T> & v);
>
> namespace outer {
>
> template<class T> class Thing { };
>
> template<typename T> std:stream & operator<< (std:stream & o,
> const Thing<T> & t);
>
> void foo() { std::vector<double> v; std::cout << v; }
>
> }
>
> int main()
> {
> return 0;
>
> }
>
> === EOF ===



 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-10-2007
On May 9, 4:37 pm, mrstephengross <mrstephengr...@hotmail.com> 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<T> to a std:stream.


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<T> to a std:stream.
> In the "outer" namespace, I've got a function "foo" that tries to send
> a vector<T> to a std:stream.


> 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<typename T> std:stream & operator<< (std:stream & o,
> const std::vector<T> & v);


> namespace outer {


> template<class T> class Thing { };


> template<typename T> std:stream & operator<< (std:stream & o,
> const Thing<T> & t);


> void foo() { std::vector<double> v; 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<double> in
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:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
del operator and global namespace alust Python 1 12-08-2010 06:32 PM
FWSM/PIX and Dynamic PAT using global IP range vs. global interface vs. global IP Hoffa Cisco 1 10-25-2006 06:50 PM
FWSM/PIX and Dynamic PAT using global IP range vs. global interface vs. global IP Hoffa Cisco 0 10-25-2006 01:04 PM
operator<<() in namespace or global? ryan_melville@xiotech.com C++ 2 08-14-2006 05:57 PM
Why Wildcard masks Prashant Varghese Cisco 3 11-08-2004 11:19 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57