473,387 Members | 1,779 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Problems of overloading template operator >>

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
4 2453
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

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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: maths_fan | last post by:
Can't understand how to overload these operations and for what reason?
1
by: bluekite2000 | last post by:
I have template <typename T> inline std::istream& operator >> (std::istream& is, Matrix<T>& mIn) { int rows,cols; is.clear(); is >> rows >> cols; mIn._M=rows; mIn._N=cols;...
4
by: Don Hedgpeth | last post by:
Here's a question - I'm new to c++ and I have two classes that overload the >> operator. One class calls the other...such as. //code for class1 friend std::istream& operator >> (std::istream&...
6
by: n2xssvv g02gfr12930 | last post by:
Does anyone know of an example of overloading operator ->* Cheers JB
4
by: jelle | last post by:
Hi, I use python quite a bit to couple different programs together. Doing so has been a _lot_ easier since subprocess came around, but would really like to be able to use the succinct shell...
11
by: Ashwin | last post by:
hi guys, i have overloaded >operator for my own string class .the function is as given below istream& operator>>(istream &in,string1 &s) { char *a; a=new char; in>>a; s=a;
0
by: rama270 | last post by:
Problem: The operator -> is overloaded thus Class * operator-> () { return this; } but this causes a problem for const member functions . The purpose of overloading is that both . and -> can be...
3
by: Demoris | last post by:
I have a class that I believe should work. I've compared it to previous programs I've written, compared it to examples from my professor, to examples in my textbook, but can't see why I get the...
9
by: Nico | last post by:
I want to create a const_iterator that gives me access to dynamically generated objects. For example see the class Polygon that contains a list of points stored as following doubles in a vector...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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...

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.