By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,332 Members | 1,404 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,332 IT Pros & Developers. It's quick & easy.

operators & namespaces

P: n/a
Hi,

I have a little problem with classes in a namespace and an operator
defined for these classes outside that namespace. Example:

// -------------------------------------------------------------------
#include <iostream>
#include <vector>

namespace N {
struct A { int a; };
A& operator<<(A& a, int i)
{ std::cout << "i=" << i << '\n'; return a; }
A& operator<<(A& a, float f)
{ std::cout << "f=" << f << '\n'; return a; }
}

template<typename T>
void WriteVector(N::A& a, std::vector<Tconst& v)
{
typename std::vector<T>::const_iterator it;
for( it=v.begin(); it!=v.end(); ++it )
a << *it;
}

template<typename T>
inline N::A& operator<<(N::A& a, std::vector<Tconst& v)
{ WriteVector( a, v ); return a; }

namespace N {
void go() {
std::vector<intv;
for( int i=0; i<5; ++i )
v.push_back( 1<<i );
A a;
WriteVector( a, v );
a << v;
}
}
int main()
{
N::go();
}
// -------------------------------------------------------------------

The compiler (g++) gives me the following error message:

################################################## ####################
In function 'void N::go()':
error: no match for 'operator<<' in 'a << v'
note: candidates are: N::A& N::operator<<(N::A&, int)
note: N::A& N::operator<<(N::A&, float)
################################################## ####################

So while the operator<< template is not found, the WriteVector version
is. How can I help the compiler to find the operator<< version?

Thanks for your advice,

Alexander

PS: For email reply, please remove the six appropriate letters from the
given address.
Nov 4 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Alexander Bürger wrote:
Hi,

I have a little problem with classes in a namespace and an operator
defined for these classes outside that namespace. Example:

// -------------------------------------------------------------------
#include <iostream>
#include <vector>

namespace N {
struct A { int a; };
A& operator<<(A& a, int i)
{ std::cout << "i=" << i << '\n'; return a; }
A& operator<<(A& a, float f)
{ std::cout << "f=" << f << '\n'; return a; }
You can either add a prototype in the namespace

template<typename T>
A& operator<<(A& a, std::vector<Tconst& );
}

template<typename T>
void WriteVector(N::A& a, std::vector<Tconst& v)
{
typename std::vector<T>::const_iterator it;
for( it=v.begin(); it!=v.end(); ++it )
a << *it;
}
Or put the operator in the namespace.

namespace N {
template<typename T>
inline N::A& operator<<(N::A& a, std::vector<Tconst& v)
{ WriteVector( a, v ); return a; }
}

--
Ian Collins.
Nov 4 '06 #2

P: n/a
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ian Collins :
Alexander Bürger wrote:
>Hi,

I have a little problem with classes in a namespace and an operator
defined for these classes outside that namespace. Example:

// -------------------------------------------------------------------
#include <iostream>
#include <vector>

namespace N {
struct A { int a; };
A& operator<<(A& a, int i)
{ std::cout << "i=" << i << '\n'; return a; }
A& operator<<(A& a, float f)
{ std::cout << "f=" << f << '\n'; return a; }

You can either add a prototype in the namespace

template<typename T>
A& operator<<(A& a, std::vector<Tconst& );
>}

template<typename T>
void WriteVector(N::A& a, std::vector<Tconst& v)
{
typename std::vector<T>::const_iterator it;
for( it=v.begin(); it!=v.end(); ++it )
a << *it;
}
Or put the operator in the namespace.

namespace N {
>template<typename T>
inline N::A& operator<<(N::A& a, std::vector<Tconst& v)
{ WriteVector( a, v ); return a; }
}
It is ok when using either of you method .
But , why c++ can't find the symbol , does c++
only find the definition in the namespace ?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFFTXDG7tZp58UCwyMRAsfQAJ459v/lbClnAGvcPH13fuvZGRpJXQCfcuA5
+EAKf56k76P3o3vN16lcm2o=
=JgNA
-----END PGP SIGNATURE-----
Nov 5 '06 #3

P: n/a
Hi Ian,

thank you for your answer.
You can either add a prototype in the namespace

template<typename T>
A& operator<<(A& a, std::vector<Tconst& );
Unfortunately, g++ does not like this either. Either the linker
complains or, if I write ::operator, the compiler complains that I try
to declare something in the wrong namespace.
Or put the operator in the namespace.
Of course.
It also works after replacing the operator<< functions in namespace N
with "named" functions. Apparently the compiler stops searching as soon
as it found any operator<< in namespace N, independent of the signature.
The following code compiles only if NO_B is defined:

// -------------------------------------------------------------
#include <iostream>
#include <vector>

namespace N {
struct A { int a; };
void Write( A&, int i) { std::cout << "i=" << i << '\n'; }
void Write( A&, float f) { std::cout << "f=" << f << '\n'; }
#ifndef NO_B
struct B { int b; };
B& operator<<(B& b, float f)
{ std::cout << "f=" << f << '\n'; return b; }
#endif
}

template<typename T>
void WriteVector(N::A& a, std::vector<Tconst& v)
{
typename std::vector<T>::const_iterator it;
for( it=v.begin(); it!=v.end(); ++it )
Write( a, *it );
}

template<typename T>
inline N::A& operator<<(N::A& a, std::vector<Tconst& v)
{ WriteVector( a, v ); return a; }

namespace N {
void go() {
std::vector<intv;
for( int i=0; i<5; ++i )
v.push_back( 1<<i );
A a;
a << v;
}
}
int main()
{
N::go();
}
// -------------------------------------------------------------

So I think I understood where the problem comes from, although I do see
no reason why the compiler does not search for a good signature in the
enclosing namespaces.

Best wishes,

Alexander
Nov 6 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.