Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #3432 > unrolled thread
| Started by | Ruben Safir <ruben@mrbrklyn.com> |
|---|---|
| First post | 2011-04-11 23:39 +0000 |
| Last post | 2011-04-12 08:23 +0200 |
| Articles | 10 — 5 participants |
Back to article view | Back to comp.lang.c++
templated operator()<< Ruben Safir <ruben@mrbrklyn.com> - 2011-04-11 23:39 +0000
Re: templated operator()<< LR <lruss@superlink.net> - 2011-04-11 20:07 -0400
Re: templated operator()<< "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-04-12 02:29 +0200
Re: templated operator()<< Ruben Safir <ruben@mrbrklyn.com> - 2011-04-12 01:59 +0000
Re: templated operator()<< "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-04-12 04:01 +0200
Re: templated operator()<< Ruben Safir <ruben@mrbrklyn.com> - 2011-04-12 02:37 +0000
Re: templated operator()<< Ruben Safir <ruben@mrbrklyn.com> - 2011-04-12 02:43 +0000
Re: templated operator()<< "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-04-12 05:25 +0200
Re: templated operator()<< Michael Doubez <michael.doubez@free.fr> - 2011-04-12 00:17 -0700
Re: templated operator()<< Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-04-12 08:23 +0200
| From | Ruben Safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2011-04-11 23:39 +0000 |
| Subject | templated operator()<< |
| Message-ID | <io03f9$qsv$1@reader1.panix.com> |
as I understand things, the operator<<() needs to be external as to the
class and then declared as a friend of the class. I'm not sure if I
understand why that is the case.
I did this with a class called MESSAGE and had not trouble with the
general implementation. However, when I tried to do this with a
templated class that generally looks like, although this is not compiling
namespace stats{
template<class T>
class Distribution {
template<T> friend std::ostream & operator<<(std::ostream &, const Distribution<T>&);
public:
/* ==================== LIFECYCLE ======================================= */
Distribution (T descr, int occurances = 0);
Distribution():freq(NULL),occurances(NULL){};
// Distribution ( const Distribution &other ); /* copy constructor */
// ~Distribution (); /* destructor */
/* ==================== ACCESSORS ======================================= */
T description(){ return freq;}
int population() { return occurances; }
/* ==================== MUTATORS ======================================= */
void increase_occ(){ ++occurances; std::cout << "description " << freq << " occurances " << occurances << std::endl; }
void descrease_occ(){ --occurances; }
/* ==================== OPERATORS ======================================= */
//Distribution& operator = ( const Distribution &other ); /* assignment operator */
int operator()(){
return freq;
}
bool operator==(Distribution &tmp){
if(this->freq == tmp.freq)
return true;
return false;
}
bool operator<(Distribution &tmp){
if(freq < tmp.freq)
return true;
return false;
}
protected:
/* ==================== DATA MEMBERS ======================================= */
private:
/* ==================== DATA MEMBERS ======================================= */
T freq; //description of how many times found in a List
int occurances; //description of how many times a frequency was found in a list
}; /* ----- end of class Distribution ----- */
template<typename T>
std::ostream & operator << ( std::ostream & os, const Distribution<T> & obj )
{
T desc = obj.description();
int pop = obj.population();
os << "The Identification of " << desc << " was seens " << pop ;
return os;
} /* ----- end of function operator << ----- */
Not this is not compiling because:
test_del.cpp|90| error: passing ‘const stats::Distribution<int>’ as ‘this’ argument of ‘T stats::Distribution<T>::description() [with T = int]’ discards qualifiers
which is on the call for the use of the << operator on the class. before I templated
the operaotr<<(), I got a warning that I was using a non-templated function. I've done some research and this
peoblem seems to have been common, but I don't know of any solutions, and I don't understand what the implementation
issue is.
[toc] | [next] | [standalone]
| From | LR <lruss@superlink.net> |
|---|---|
| Date | 2011-04-11 20:07 -0400 |
| Message-ID | <4da397d1$0$8789$cc2e38e6@news.uslec.net> |
| In reply to | #3432 |
Ruben Safir wrote:
[snippage]
> I did this with a class called MESSAGE and had not trouble with the
> general implementation. However, when I tried to do this with a
> templated class that generally looks like, although this is not compiling
>
> namespace stats{
>
> template<class T>
> class Distribution {
> template<T> friend std::ostream & operator<<(std::ostream &, const Distribution<T>&);
> public:
> T description(){ return freq;}
> int population() { return occurances; }
> }; /* ----- end of class Distribution ----- */
>
>
> template<typename T>
> std::ostream & operator << ( std::ostream & os, const Distribution<T> & obj )
> {
obj is const, but obj.description() isn't.
> T desc = obj.description();
> int pop = obj.population();
> test_del.cpp|90| error: passing ‘const stats::Distribution<int>’ as ‘this’ argument of ‘T stats::Distribution<T>::description() [with T = int]’ discards qualifiers
change stats::Distribution::description to
T description() const { return freq; }
similarly, I think, with stats::Distribution::population().
LR
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2011-04-12 02:29 +0200 |
| Message-ID | <io06co$fgm$1@dont-email.me> |
| In reply to | #3432 |
* Ruben Safir, on 12.04.2011 01:39: > as I understand things, the operator<<() needs to be external as to the > class and then declared as a friend of the class. I'm not sure if I > understand why that is the case. It's not the case. ;-) [snip question that's apparently already answered] Cheers & hth., - Alf -- blog at <url: http://alfps.wordpress.com>
[toc] | [prev] | [next] | [standalone]
| From | Ruben Safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2011-04-12 01:59 +0000 |
| Message-ID | <io0bl5$9hr$1@reader1.panix.com> |
| In reply to | #3438 |
On Tue, 12 Apr 2011 02:29:10 +0200, Alf P. Steinbach /Usenet wrote: > * Ruben Safir, on 12.04.2011 01:39: >> as I understand things, the operator<<() needs to be external as to the >> class and then declared as a friend of the class. I'm not sure if I >> understand why that is the case. > what?? operator<<() can be a normal class member? > It's not the case. ;-) > > > [snip question that's apparently already answered] > > Cheers & hth., > > - Alf
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2011-04-12 04:01 +0200 |
| Message-ID | <io0bpn$dph$2@dont-email.me> |
| In reply to | #3439 |
* Ruben Safir, on 12.04.2011 03:59: > On Tue, 12 Apr 2011 02:29:10 +0200, Alf P. Steinbach /Usenet wrote: > >> * Ruben Safir, on 12.04.2011 01:39: >>> as I understand things, the operator<<() needs to be external as to the >>> class and then declared as a friend of the class. I'm not sure if I >>> understand why that is the case. >> > > > what?? operator<<() can be a normal class member? Yes. Cheers & hth., - Alf -- blog at <url: http://alfps.wordpress.com>
[toc] | [prev] | [next] | [standalone]
| From | Ruben Safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2011-04-12 02:37 +0000 |
| Message-ID | <io0dtf$qsv$2@reader1.panix.com> |
| In reply to | #3441 |
On Tue, 12 Apr 2011 04:01:25 +0200, Alf P. Steinbach /Usenet wrote:
> * Ruben Safir, on 12.04.2011 03:59:
>> On Tue, 12 Apr 2011 02:29:10 +0200, Alf P. Steinbach /Usenet wrote:
>>
>>> * Ruben Safir, on 12.04.2011 01:39:
>>>> as I understand things, the operator<<() needs to be external as to
>>>> the class and then declared as a friend of the class. I'm not sure
>>>> if I understand why that is the case.
>>>
>>>
>>
>> what?? operator<<() can be a normal class member?
>
> Yes.
>
>
> Cheers & hth.,
>
> - Alf
http://www.google.com/url?sa=t&source=web&cd=6&ved=0CD4QFjAF&url=http%3A%2F%2Fwww.cs.duke.edu%2Fcsed%2Ftapestry%2Fhowtoe.pdf&ei=5LejTczhDsLVgQfbrLmeCg&usg=AFQjCNHOXIvtfFFJPEpToqsEn6P_sXqPuw&sig2=fIiugNyxWwZH49lWIYorug
and other locations (on in ym text books)
We’ll look first at overloading the insertion operator, operator <<, for stream output.
Here it’s absolutely not possible to make the operator a member function of the class for
which output is being defined. The statement
cout << x;
could be interpreted by the compiler as cout.operator <<(x) , where the inser-
tion operator is a member function of the ostream class of which cout is an instance.
The insertion operator could also be a free function with two parameters, much like
operator + is as discussed above. Since programmers don’t typically have access to
redefining the standard I/O classes, the I/O operators are typically implemented as free
functions. The header for the insertion operator for BigInt is shown below.
ostream& operator <<(ostream & out, const BigInt & big)
// postcondition: big inserted onto stream out
The return type must be a reference type because the stream on which the object is
inserted is returned for subsequent insertion operations. This is what allows insertions
to be chained together:
BigInt b = factorial(val);
string s = " factorial = ";
cout << s << b;
The last statement could be written more cumbersomely as follows since operator <<
is overloaded as a free function for both string and BigInt objects.
operator << (operator << (cout,s), b);
However, it’s essential that operator << be an operator and not a function since the
order in which arguments are evaluated in C++ is not defined. In the statement x =
min(sqrt(x),sqrt(y)), compilers are not required to evaluate sqrt(x) before
evaluating sqrt(y) (this is a C legacy, it’s too bad that the order in which arguments
are evaluated isn’t prescribed). However, the associativity of operator << is defined,
it’s left associative, which means that
cout << x << y << z;
requires that x be inserted before y, and that y be inserted before z.
Now that we know the prototype for the overloaded operator <<, how do we
implement the operator? As with overloaded arithmetic operators there are two choices:
Make operator << a friend of the class whose output is being overloaded, for
example, of BigInt in the examples above.
Create a member function that can be used in implementing operator << as a
free, nonfriend function.
June 7, 1999 10:10 owltex Sheet number 31 Page number 754 magenta black
754 Appendix E How to: Overload Operators
We’ll adopt the second approach, since it avoids the coupling entailed by creating
friend classes and the solution we’ll use is easily extensible to other, nonstream output,
such as on a graphics display.
[toc] | [prev] | [next] | [standalone]
| From | Ruben Safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2011-04-12 02:43 +0000 |
| Message-ID | <io0e7q$qsv$3@reader1.panix.com> |
| In reply to | #3441 |
On Tue, 12 Apr 2011 04:01:25 +0200, Alf P. Steinbach /Usenet wrote: > * Ruben Safir, on 12.04.2011 03:59: >> On Tue, 12 Apr 2011 02:29:10 +0200, Alf P. Steinbach /Usenet wrote: >> >>> * Ruben Safir, on 12.04.2011 01:39: >>>> as I understand things, the operator<<() needs to be external as to >>>> the class and then declared as a friend of the class. I'm not sure >>>> if I understand why that is the case. >>> >>> >> >> what?? operator<<() can be a normal class member? > > Yes. > > > Cheers & hth., > > - Alf http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading#Operators_as_member_functions Of special mention are the shift operators, << and >>. These have been overloaded in the standard library for interaction with streams. When overloading these operators to work with streams the rules below should be followed: 1. overload << and >> as friends (so that it can access the private variables with the stream be passed in by references 2. (input/output modifies the stream, and copying is not allowed) 3. the operator should return a reference to the stream it receives (to allow chaining, cout << 3 << 4 << 5)
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2011-04-12 05:25 +0200 |
| Message-ID | <io0gn3$3ie$1@dont-email.me> |
| In reply to | #3443 |
* Ruben Safir, on 12.04.2011 04:43: > On Tue, 12 Apr 2011 04:01:25 +0200, Alf P. Steinbach /Usenet wrote: > >> * Ruben Safir, on 12.04.2011 03:59: >>> On Tue, 12 Apr 2011 02:29:10 +0200, Alf P. Steinbach /Usenet wrote: >>> >>>> * Ruben Safir, on 12.04.2011 01:39: >>>>> as I understand things, the operator<<() needs to be external as to >>>>> the class and then declared as a friend of the class. I'm not sure >>>>> if I understand why that is the case. >>>> >>>> >>> >>> what?? operator<<() can be a normal class member? >> >> Yes. >> >> >> Cheers& hth., >> >> - Alf > http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading#Operators_as_member_functions > > > Of special mention are the shift operators,<< and>>. These have been overloaded in the standard library for interaction with streams. When overloading these operators to work with streams the rules below should be followed: > > 1. overload<< and>> as friends (so that it can access the private variables with the stream be passed in by references > 2. (input/output modifies the stream, and copying is not allowed) > 3. the operator should return a reference to the stream it receives (to allow chaining, cout<< 3<< 4<< 5) Your question seems to be missing. Cheers & hth., - Alf -- blog at <url: http://alfps.wordpress.com>
[toc] | [prev] | [next] | [standalone]
| From | Michael Doubez <michael.doubez@free.fr> |
|---|---|
| Date | 2011-04-12 00:17 -0700 |
| Message-ID | <30b6491c-c5bb-430a-9e0e-d99d2bdecfb0@dr5g2000vbb.googlegroups.com> |
| In reply to | #3445 |
On 12 avr, 05:25, "Alf P. Steinbach /Usenet" <alf.p.steinbach +use...@gmail.com> wrote: > * Ruben Safir, on 12.04.2011 04:43: > > > On Tue, 12 Apr 2011 04:01:25 +0200, Alf P. Steinbach /Usenet wrote: > > >> * Ruben Safir, on 12.04.2011 03:59: > >>> On Tue, 12 Apr 2011 02:29:10 +0200, Alf P. Steinbach /Usenet wrote: > > >>>> * Ruben Safir, on 12.04.2011 01:39: > >>>>> as I understand things, the operator<<() needs to be external as to > >>>>> the class and then declared as a friend of the class. I'm not sure > >>>>> if I understand why that is the case. > > >>> what?? operator<<() can be a normal class member? > > >> Yes. > > > >http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overl... > > > Of special mention are the shift operators,<< and>>. These have been overloaded in the standard library for interaction with streams. When overloading these operators to work with streams the rules below should be followed: > > > 1. overload<< and>> as friends (so that it can access the private variables with the stream be passed in by references > > 2. (input/output modifies the stream, and copying is not allowed) > > 3. the operator should return a reference to the stream it receives (to allow chaining, cout<< 3<< 4<< 5) > > Your question seems to be missing. Because IMHO your answer was misleading. Tes, In the general case, operator<<() - i.e. shift operator - can be defined as a member function. AFAIS Ruben Safier was asking about operator<<() for stream output. In this case, yes, he must defined it as a free function (friend or not). -- Michael
[toc] | [prev] | [next] | [standalone]
| From | Kai-Uwe Bux <jkherciueh@gmx.net> |
|---|---|
| Date | 2011-04-12 08:23 +0200 |
| Message-ID | <io0r4d$6c2$1@hoshi.visyn.net> |
| In reply to | #3439 |
Ruben Safir wrote: > On Tue, 12 Apr 2011 02:29:10 +0200, Alf P. Steinbach /Usenet wrote: > >> * Ruben Safir, on 12.04.2011 01:39: >>> as I understand things, the operator<<() needs to be external as to the >>> class and then declared as a friend of the class. I'm not sure if I >>> understand why that is the case. >> > > > what?? operator<<() can be a normal class member? Yes, operator<< can be a normal class member. That says that the expression a << b (*) where a is of type A and b is of type B can be interpreted in two ways: 1) operator<<( a, b ) 2) a.operator<<(b) That is, in (*) the operator<< could be a member function of A. Even if B has a member function operator<<(), it is not be used to interpret (*). Hence, when declaring output operators for the use with ostreams, it does not help to make them member functions of the class you want to set up for output. However, when deriving from streams, you can make them member functions. Best, Kai-Uwe Bux
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web