Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #3432 > unrolled thread

templated operator()<<

Started byRuben Safir <ruben@mrbrklyn.com>
First post2011-04-11 23:39 +0000
Last post2011-04-12 08:23 +0200
Articles 10 — 5 participants

Back to article view | Back to comp.lang.c++


Contents

  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

#3432 — templated operator()<<

FromRuben Safir <ruben@mrbrklyn.com>
Date2011-04-11 23:39 +0000
Subjecttemplated 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]


#3436

FromLR <lruss@superlink.net>
Date2011-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]


#3438

From"Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date2011-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]


#3439

FromRuben Safir <ruben@mrbrklyn.com>
Date2011-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]


#3441

From"Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date2011-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]


#3442

FromRuben Safir <ruben@mrbrklyn.com>
Date2011-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]


#3443

FromRuben Safir <ruben@mrbrklyn.com>
Date2011-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]


#3445

From"Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
Date2011-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]


#3452

FromMichael Doubez <michael.doubez@free.fr>
Date2011-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]


#3449

FromKai-Uwe Bux <jkherciueh@gmx.net>
Date2011-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