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

Problems of overloading template operator >>

P: n/a
Hi all.

I have run into a problem of overloading a templatized operator>> by a
specialized version of it. In short (complete code below), I have
written a stream class, STR, which defines a templatized operator>>() as
a member that can deal with the built in C types (int, char, float...)

template <class tType> STR& STR::operator>>(tType & t);

I then attempted to add an overloaded version of this to support my own
class, Array3d (a template class), and wrote this as a friend of Array3d as

template <class tType>
STR & operator >> ( STR & outf, Array3d<tType> & array ){}

It all compiles, but when I run the program, the lines;

str << array // str is an STR, array is an Array3d<int>

it will call STR::operator>> <Array3d<int> >, rather than (what I
belived to be) the specialized operator>>(STR &, Array3d<int> &).

If I instead remove the STR::operator>>() and replace it by a friend
function (commented out in the code below) the function call works as i
expect it to.

Can you please enlighten me as to where I have gone wrong?

Best regards
hall


// main.cpp
//---------------------------------------------------------------------------
#pragma hdrstop
#include "IOFile_mod.h"
#include <iostream>

#pragma argsused
int main(int argc, char* argv[])
{
Array3d<int> array;
std::cout << "Operator << for Array3d\n";
STR in;
in >> array;

std::cout << "Operator << for int\n";
int i(3);
in >> i;

return 0;
}
//---------------------------------------------------------------------------

// IOFile_mod.h
//---------------------------------------------------------------------------
#ifndef IOFileH
#define IOFileH

#include <iostream>

// --------------------------------------
class STR
{
public:
template <class tType> STR& operator>>( tType & );
//template <class tType> friend STR & operator >> ( STR & of, tType
& a );
};

template <class tType>
STR& STR::operator>>( tType & obj)
{
std::cout << "STR::operator<<(const tType obj)\n";
return *this;
}

//template <class tType>
//STR & operator >> ( STR & of, tType & a ){
// std::cout << "Friend of STR\n";
// return of;
//}

// --------------------------------------
template <class tType> class Array3d;
template <class tType> STR & operator >> ( STR & of, Array3d<tType> & a );

template <class tType> class Array3d
{
public:
friend STR & operator >> <>( STR & of, Array3d<tType> & a );
};

template <class tType>
STR & operator >> ( STR & outf, Array3d<tType> & array )
{
std::cout << "STR & operator >> (STR & inf, Array3d<tType> & array )\n";
return outf;
}

#endif
//---------------------------------------------------------------------------

--
Please remove capital x from email to reply

Aug 18 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
hall wrote:
I have run into a problem of overloading a templatized operator>> by a
specialized version of it. In short (complete code below), I have
written a stream class, STR, which defines a templatized operator>>() as
a member that can deal with the built in C types (int, char, float...)

template <class tType> STR& STR::operator>>(tType & t);

I then attempted to add an overloaded version of this to support my own
class, Array3d (a template class), and wrote this as a friend of Array3d as

template <class tType>
STR & operator >> ( STR & outf, Array3d<tType> & array ){}

It all compiles, but when I run the program, the lines;

str << array // str is an STR, array is an Array3d<int>
str >> array; // ...
it will call STR::operator>> <Array3d<int> >, rather than (what I
belived to be) the specialized operator>>(STR &, Array3d<int> &).
Not on my system it won't.
If I instead remove the STR::operator>>() and replace it by a friend
function (commented out in the code below) the function call works as i
expect it to.

Can you please enlighten me as to where I have gone wrong?
[...]


For one, all over your code you mixed operator << and operator >>,
in comments and in user-visible output.

As to which version gets used, I took your code and put it in the same
file, fixed it a bit (not functionality, just visually), and here it is:
----------------------------------------------------------------------
#include <iostream>

struct STR
{
template <class tType> STR& operator >> ( tType & );
};

template <class tType>
STR& STR::operator >>( tType & obj)
{
std::cout << "MEMBER ***** STR::operator >> (const tType obj)\n";
return *this;
}

template <class tType> class Array3d;
template <class tType> STR & operator >> ( STR &, Array3d<tType> & );

template <class tType> class Array3d
{
friend STR & operator >> <>( STR & of, Array3d<tType> & a );
};

template <class tType>
STR & operator >> ( STR & outf, Array3d<tType> & array )
{
std::cout << "STAND-ALONE **** STR & operator >> (STR & inf,
Array3d<tType> & array )\n";
return outf;
}

int main()
{
STR in;

Array3d<int> array;
std::cout << "Operator >> for Array3d\n";
in >> array;

std::cout << "Operator >> for int\n";
int i(3);
in >> i;

return 0;
}
----------------------------------------------------------------------
The output of it is
----------------------------------------------------------------------
Operator >> for Array3d
STAND-ALONE **** STR & operator >> (STR & inf, Array3d<tType> & array )
Operator >> for int
MEMBER ***** STR::operator >> (const tType obj)
----------------------------------------------------------------------
So, I don't see a problem here...

V
Aug 18 '05 #2

P: n/a

Victor Bazarov wrote:

[]
----------------------------------------------------------------------
The output of it is
----------------------------------------------------------------------
Operator >> for Array3d
STAND-ALONE **** STR & operator >> (STR & inf, Array3d<tType> & array )
Operator >> for int
MEMBER ***** STR::operator >> (const tType obj)
----------------------------------------------------------------------
So, I don't see a problem here...


gcc 4.0.1 reports:

exp.cpp: In function 'int main()':
exp.cpp:51: error: ambiguous overload for 'operator>>' in 'in >> array'
exp.cpp:13: note: candidates are: STR& STR::operator>>(tType&) [with
tType = Array3d<int>]
exp.cpp:35: note: STR& operator>>(STR&,
Array3d<tType>&) [with tType =

Here are the details:

[max@localhost exp]$ g++ -v -Wall -ggdb exp.cpp -o exp
g++ -v -Wall -ggdb exp.cpp -o exp
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,java,f95,ada --enable-java-awt=gtk
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--host=i386-redhat-linux
Thread model: posix
gcc version 4.0.1 20050727 (Red Hat 4.0.1-5)
/usr/libexec/gcc/i386-redhat-linux/4.0.1/cc1plus -quiet -v
-D_GNU_SOURCE exp.cpp -quiet -dumpbase exp.cpp -auxbase exp -ggdb -Wall
-version -o /tmp/ccDs1nxR.s
ignoring nonexistent directory
"/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1

/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/i386-redhat-linux

/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/backward
/usr/local/include
/usr/lib/gcc/i386-redhat-linux/4.0.1/include
/usr/include
End of search list.
GNU C++ version 4.0.1 20050727 (Red Hat 4.0.1-5) (i386-redhat-linux)
compiled by GNU C version 4.0.1 20050727 (Red Hat 4.0.1-5).
GGC heuristics: --param ggc-min-expand=64 --param
ggc-min-heapsize=64417
exp.cpp: In function 'int main()':
exp.cpp:51: error: ambiguous overload for 'operator>>' in 'in >> array'
exp.cpp:13: note: candidates are: STR& STR::operator>>(tType&) [with
tType = Array3d<int>]
exp.cpp:35: note: STR& operator>>(STR&,
Array3d<tType>&) [with tType = int]

Aug 18 '05 #3

P: n/a
Victor Bazarov wrote:

For one, all over your code you mixed operator << and operator >>,
in comments and in user-visible output.

Sorry about that, I've been rewriting it som many times that comments
and output strings got mixed up...
So, I don't see a problem here...

V


I still do. Compiling it using Borland C++ builder 6 (my compiler of
choise) I get:

Operator >> for Array3d
MEMBER ***** STR::operator >> (const tType obj)
Operator >> for int
MEMBER ***** STR::operator >> (const tType obj)

Whereas Visual Studio.net gives the same result as you reported. I also
saw that Maxim in another answer reported that gcc 4.0.1 thought of it
as ambiguous. So which compiler gets it right, and how should this code
be written?

regards
hall

--
<- remove capital x:s from e-mail to reply ->

Aug 18 '05 #4

P: n/a
hall wrote:
Victor Bazarov wrote:
So, I don't see a problem here...

V

I still do. Compiling it using Borland C++ builder 6 (my compiler of
choise) I get:

Operator >> for Array3d
MEMBER ***** STR::operator >> (const tType obj)
Operator >> for int
MEMBER ***** STR::operator >> (const tType obj)

Whereas Visual Studio.net gives the same result as you reported. I also
saw that Maxim in another answer reported that gcc 4.0.1 thought of it
as ambiguous. So which compiler gets it right, and how should this code
be written?


I checked with Comeau online, after making the member operator in STR
private. It only complained about the input of an 'int', which makes me
think that Visual C++ gets it right and BC++ and G++ are both faulty.

Come to think of it, the non-member template function is actually more
specialised, so overload resolution should pick it over the less
specialised member template operator>>. That's what I think, anyway.

I suggest you contact Borland newsgroup and/or GNU C++ folk and see what
they think. Feel free to quote me.

V
Aug 18 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.