Strange compiler error w.r.t 'friend ostream& operator<< <>(ostream&,...)'

A

abhay.burli

I have the following piece of code ...

NOTE: I have intentionally qualified 'ostream' and 'cout' with 'std::'
for the purposes of the example

#include<iostream>
using namespace std;

template<class T>
class SomeClass{
public:
SomeClass(const T& a) : member(a)
{
}
friend std::eek:stream& operator<< <>(std::eek:stream &,SomeClass <T>&);
private:
T member;
};

template <typename T>
std::eek:stream& operator<< (std::eek:stream &os, SomeClass<T>&some)
{
os<<"( " << some.member <<") ";
return os;
}

int main(int argc, char* argv[])
{
SomeClass<int> sc(5);
std::cout << sc;
return 0;
}

This compiles fine.
Now just comment out the line 'using namespace std;' and comeau spits
out the following ...
<--------------------------------------------------------------------------------------Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for
ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 11: error: operator<< is not a template,
Should it be XX::eek:perator<<?, where XX is some namespace?
Did you #include the right header?
friend std::eek:stream& operator<< <>(std::eek:stream &,SomeClass <T>&);
^

"ComeauTest.c", line 19: error: member "SomeClass<T>::member [with
T=int]" (declared
at line 13) is inaccessible
os<<"( " <<some.member <<") ";
^
detected during instantiation of "std::eek:stream
&operator<<(std::eek:stream &, SomeClass<T> &) [with
T=int]"
at line 26

2 errors detected in the compilation of "ComeauTest.c".
<--------------------------------------------------------------------------------------
and following from MSVC 2005 (Team Edition) is worse ...
<--------------------------------------------------------------------------------------1>Compiling...
1>Hello World.cpp
1>.\Hello World.cpp(2112) : error C2143: syntax error : missing ';'
before '<'
1> .\Hello World.cpp(2113) : see reference to class template
instantiation 'S<T>' being compiled
1>.\Hello World.cpp(2112) : error C2433: '<<' : 'friend' not permitted
on data declarations
1>.\Hello World.cpp(2112) : error C2530: '<<' : references must be
initialized
1>.\Hello World.cpp(2112) : error C2238: unexpected token(s) preceding
';'
1>.\Hello World.cpp(2119) : error C2365: '<<' : redefinition; previous
definition was 'data variable'
1> .\Hello World.cpp(2112) : see declaration of '<<'
1>.\Hello World.cpp(2119) : error C2904: '<<' : name already used for
a template in the current scope
1> .\Hello World.cpp(2112) : see declaration of '<<'
1>.\Hello World.cpp(2112) : error C2143: syntax error : missing ';'
before '<'
1> .\Hello World.cpp(2124) : see reference to class template
instantiation 'S<T>' being compiled
1> with [... a long template instantiation error ... ]
<--------------------------------------------------------------------------------------
Why??
 
A

Annie Testes

I have the following piece of code ...

NOTE: I have intentionally qualified 'ostream' and 'cout' with 'std::'
for the purposes of the example

#include<iostream>
using namespace std;

template<class T>
class SomeClass{
public:
SomeClass(const T& a) : member(a)
{
}
friend std::eek:stream& operator<< <>(std::eek:stream &,SomeClass <T>&);
private:
T member;
};

template <typename T>
std::eek:stream& operator<< (std::eek:stream &os, SomeClass<T>&some)
{
os<<"( " << some.member <<") ";
return os;
}

int main(int argc, char* argv[])
{
SomeClass<int> sc(5);
std::cout << sc;
return 0;
}

This compiles fine.

The above doesn't compile with gcc (4.3.3)
(either with and without 'using namespace std'):

yyy.cc: In instantiation of ‘SomeClass<int>’:
yyy.cc:27: instantiated from here
yyy.cc:11: error: template-id ‘operator<< <>’ for ‘std::eek:stream&
operator<<(std::eek:stream&, SomeClass<int>&)’ does not match any
template declaration
yyy.cc: In function ‘std::eek:stream& operator<<(std::eek:stream&,
SomeClass<T>&) [with T = int]’:
yyy.cc:28: instantiated from here
yyy.cc:13: error: ‘int SomeClass<int>::member’ is private
yyy.cc:20: error: within this context

If I forward-declare SomeClass and operator<<, it compiles fine
(both with and without 'using namespace std'):

#include<iostream>
//using namespace std;

template <class T>
class SomeClass;

template <class T>
std::eek:stream& operator<<(std::eek:stream &,SomeClass <T>&);

template<class T>
class SomeClass{
public:
SomeClass(const T& a) : member(a)
{
}
friend std::eek:stream& operator<< <>(std::eek:stream &,SomeClass
<T>&);
private:
T member;

};

template <typename T>
std::eek:stream& operator<< (std::eek:stream &os, SomeClass<T>&some)
{
os<<"( " << some.member <<") ";
return os;

}

int main(int argc, char* argv[])
{
SomeClass<int> sc(5);
std::cout << sc;
return 0;

}

[skip Comeau and MSVC errors]

I have no idea why the using directive would change anything.
 
A

abhay.burli

If I forward-declare SomeClass and operator<<, it compiles fine
(both with and without 'using namespace std'):

#include<iostream>
//using namespace std;

template <class T>
class SomeClass;

template <class T>
std::eek:stream& operator<<(std::eek:stream &,SomeClass <T>&);

Thanks. This serves my purpose for now. I did not want the *evil*
'using namespace std;' in my code.
I have no idea why the using directive would change anything.- Hide quoted text -

Yes, it is really strange or maybe I am relatively new to the world of
C++ templates!

Regards,
Abhay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top