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


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

Overloading << to accept "multiple right parameters"

Started byBubba <nickname@banelli.biz.invalid>
First post2011-06-28 19:14 +0000
Last post2011-06-29 14:31 -0500
Articles 7 — 5 participants

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


Contents

  Overloading << to accept "multiple right parameters" Bubba <nickname@banelli.biz.invalid> - 2011-06-28 19:14 +0000
    Re: Overloading << to accept "multiple right parameters" Robert Wessel <robertwessel2@yahoo.com> - 2011-06-28 14:39 -0500
      Re: Overloading << to accept "multiple right parameters" Bubba <nickname@banelli.biz.invalid> - 2011-06-28 20:59 +0000
        Re: Overloading << to accept "multiple right parameters" Ian Collins <ian-news@hotmail.com> - 2011-06-29 09:14 +1200
    Re: Overloading << to accept "multiple right parameters" Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-06-29 00:23 +0200
      Re: Overloading << to accept "multiple right parameters" Bubba <nickname@banelli.biz.invalid> - 2011-06-29 08:28 +0000
        Re: Overloading << to accept "multiple right parameters" Paavo Helde <myfirstname@osa.pri.ee> - 2011-06-29 14:31 -0500

#7211 — Overloading << to accept "multiple right parameters"

FromBubba <nickname@banelli.biz.invalid>
Date2011-06-28 19:14 +0000
SubjectOverloading << to accept "multiple right parameters"
Message-ID<Xns9F12D7FE582CAbubbachipsetone@130.133.4.11>
Greetings,

I don't know whether I have stipulated subject correctly, but this is what 
I need.

There is a class that consists of a STL map<string,short>, amongst other 
interfaces. Operator << should accept a string as right parameter. After 
that string, it should again be possible to enter either string or number. 
If number is entered, then it is associated with a map, if another string 
is entered, new member of map is created. Expression must end with a 
number and that number should be associated with all strings in the map. 
If it doesn't, it should throw an exception.

IOW, it should look like this:

mVar1 << "string1" << 2; //one entry in map, with values "string1",2
mVar2 << "string2" << "string3" << "string4" << 10; //three map entries
    	    	    	    	    	    	    	    	    	    //each with short 
    	    	    	    	    	    	    	    	    	    //valeu of 10

I'm simply clueless about what should I even Google for in order to 
implement something like that, let alone do it. Manipulating with map STL 
within the implementation is not a problem (I suppose?), but syntax and 
idea behind those multiple parameters is what bugs me...

TIA!

-- 
"If you lie to the compiler,
it will get its revenge."
Henry Spencer
2.718281828459045235360287471352662497757247093699959574966967627.com

[toc] | [next] | [standalone]


#7212

FromRobert Wessel <robertwessel2@yahoo.com>
Date2011-06-28 14:39 -0500
Message-ID<0qak07dol2c633voqef904crsv4ual05n3@4ax.com>
In reply to#7211
On 28 Jun 2011 19:14:31 GMT, Bubba <nickname@banelli.biz.invalid>
wrote:

>Greetings,
>
>I don't know whether I have stipulated subject correctly, but this is what 
>I need.
>
>There is a class that consists of a STL map<string,short>, amongst other 
>interfaces. Operator << should accept a string as right parameter. After 
>that string, it should again be possible to enter either string or number. 
>If number is entered, then it is associated with a map, if another string 
>is entered, new member of map is created. Expression must end with a 
>number and that number should be associated with all strings in the map. 
>If it doesn't, it should throw an exception.
>
>IOW, it should look like this:
>
>mVar1 << "string1" << 2; //one entry in map, with values "string1",2
>mVar2 << "string2" << "string3" << "string4" << 10; //three map entries
>    	    	    	    	    	    	    	    	    	    //each with short 
>    	    	    	    	    	    	    	    	    	    //valeu of 10
>
>I'm simply clueless about what should I even Google for in order to 
>implement something like that, let alone do it. Manipulating with map STL 
>within the implementation is not a problem (I suppose?), but syntax and 
>idea behind those multiple parameters is what bugs me...



The "multiple operator" thing is an interesting hack - it isn't
actually any such thing, it just looks that way.  What actually
happens with streams is that the overload for operator<< *returns* the
stream, thus the next << has the stream as its left operand, just like
the prior <<.  So typically you have something like:

  ostream& operator<< (ostream& os, const string& str);

and when you write:

  cout << s1 <<s1;

what happens is that "cout << s1" is evaluated first and effectively
does "ostream::operator<<(cout, s1)".  The return value of that is
cout, so the second insert is effectively "cout << s2", and executes
as "ostream::operator<<(cout, s2)".

IOW, when you define your actual function, it would be something like:

  ostream& ostream::operator<< (ostream& os, const string& str)
  {
  /* do something with str */
  return os;
  }

[toc] | [prev] | [next] | [standalone]


#7216

FromBubba <nickname@banelli.biz.invalid>
Date2011-06-28 20:59 +0000
Message-ID<Xns9F12E9C2E153Fbubbachipsetone@130.133.4.11>
In reply to#7212
Robert Wessel's log on stardate 28 lip 2011

> The "multiple operator" thing is an interesting hack - it isn't
> actually any such thing, it just looks that way.  What actually
> happens with streams is that the overload for operator<< *returns*
> the stream, thus the next << has the stream as its left operand, just
> like the prior <<.  So typically you have something like:
> 
>   ostream& operator<< (ostream& os, const string& str);
> 
> and when you write:
> 
>   cout << s1 <<s1;
> 
> what happens is that "cout << s1" is evaluated first and effectively
> does "ostream::operator<<(cout, s1)".  The return value of that is
> cout, so the second insert is effectively "cout << s2", and executes
> as "ostream::operator<<(cout, s2)".
> 
> IOW, when you define your actual function, it would be something
> like: 
> 
>   ostream& ostream::operator<< (ostream& os, const string& str)
>   {
>   /* do something with str */
>   return os;
>   }

But I'm not in to stream at all. :)

I want to overload operator << in a fashion that it can accept both string 
and short as parameter and it is implemented as I described above.

For example,

		void operator<< (const string &mPar) {
			mMap.insert (pair<string,short>(mPar,0));
        }

works if I write

mVar1 << "string1";

However, in this case

mVar1 << "string1" << "string2";

error C2296: '<<' : illegal, left operand has type 'void'
error C2297: '<<' : illegal, right operand has type 'const char [8]'

And I need

mVar1 << "string1" << "string2" << 100;

to create two entries in mMap with values <"string1",100> and 
<"string2",100>.

Thanks anyway!

-- 
"If you lie to the compiler,
it will get its revenge."
Henry Spencer
2.718281828459045235360287471352662497757247093699959574966967627.com

[toc] | [prev] | [next] | [standalone]


#7217

FromIan Collins <ian-news@hotmail.com>
Date2011-06-29 09:14 +1200
Message-ID<96uuhqFfpqU2@mid.individual.net>
In reply to#7216
On 06/29/11 08:59 AM, Bubba wrote:
> Robert Wessel's log on stardate 28 lip 2011
>
>> The "multiple operator" thing is an interesting hack - it isn't
>> actually any such thing, it just looks that way.  What actually
>> happens with streams is that the overload for operator<<  *returns*
>> the stream, thus the next<<  has the stream as its left operand, just
>> like the prior<<.  So typically you have something like:
>>
>>    ostream&  operator<<  (ostream&  os, const string&  str);
>>
>> and when you write:
>>
>>    cout<<  s1<<s1;
>>
>> what happens is that "cout<<  s1" is evaluated first and effectively
>> does "ostream::operator<<(cout, s1)".  The return value of that is
>> cout, so the second insert is effectively "cout<<  s2", and executes
>> as "ostream::operator<<(cout, s2)".
>>
>> IOW, when you define your actual function, it would be something
>> like:
>>
>>    ostream&  ostream::operator<<  (ostream&  os, const string&  str)
>>    {
>>    /* do something with str */
>>    return os;
>>    }
>
> But I'm not in to stream at all. :)
>
> I want to overload operator<<  in a fashion that it can accept both string
> and short as parameter and it is implemented as I described above.
>
> For example,
>
> 		void operator<<  (const string&mPar) {
> 			mMap.insert (pair<string,short>(mPar,0));
>          }
>
> works if I write
>
> mVar1<<  "string1";
>
> However, in this case
>
> mVar1<<  "string1"<<  "string2";
>
> error C2296: '<<' : illegal, left operand has type 'void'
> error C2297: '<<' : illegal, right operand has type 'const char [8]'

Your operator has the wrong return type for chaining.  Here is a short 
example of some code I've use for std::vector.  Expanding for std::map 
shouldn't be too hard.

#include <vector>
#include <iostream>
#include <algorithm>

template <typename T>
std::vector<T>& operator<<( std::vector<T>& vector, T v )
{
   vector.push_back(v);
   return vector;
}

void print( int n ) { std::cout << n << std::endl; }

int main()
{
   std::vector<int> v;

   v << 1 << 2;

   std::for_each( v.begin(), v.end(), print );
}

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#7218

FromKai-Uwe Bux <jkherciueh@gmx.net>
Date2011-06-29 00:23 +0200
Message-ID<iudk9k$9ru$1@hoshi.visyn.net>
In reply to#7211
Bubba wrote:

> Greetings,
> 
> I don't know whether I have stipulated subject correctly, but this is what
> I need.
> 
> There is a class that consists of a STL map<string,short>, amongst other
> interfaces. Operator << should accept a string as right parameter. After
> that string, it should again be possible to enter either string or number.
> If number is entered, then it is associated with a map, if another string
> is entered, new member of map is created. Expression must end with a
> number and that number should be associated with all strings in the map.
> If it doesn't, it should throw an exception.
> 
> IOW, it should look like this:
> 
> mVar1 << "string1" << 2; //one entry in map, with values "string1",2
> mVar2 << "string2" << "string3" << "string4" << 10; //three map entries
>     //each with short
>     //valeu of 10
> 
> I'm simply clueless about what should I even Google for in order to
> implement something like that, let alone do it. Manipulating with map STL
> within the implementation is not a problem (I suppose?), but syntax and
> idea behind those multiple parameters is what bugs me...

What about something like this:


#include <iostream>
#include <vector>
#include <map>
#include <string>

class example {

  typedef std::map< std::string, int > table;

  table data;

  struct proxy {

    example * where;
    
    std::vector< std::string > stored;

    proxy ( example * ptr )
      : where ( ptr )
      , stored ()
    {}
    
    proxy & operator<< ( std::string const & str ) {
      stored.push_back( str );
      return ( *this );
    }

    proxy & operator<< ( int i ) {
      while ( ! stored.empty() ) {
	(where->data)[ stored.back() ] = i;
	stored.pop_back();
      }
      return ( *this );
    }

  };

public:

  void dump ( std::ostream & ostr ) {
    for ( table::const_iterator iter = data.begin();
	  iter != data.end(); ++iter ) {
      ostr << iter->first << " : " << iter->second << "\n";
    }
  }

  proxy operator<< ( std::string const & str ) {
    return ( proxy( this ) << str );
  }

};

int main ( void ) {
  example a;
  a << "a" << "b" << 1
    << "c" << 2;
  a.dump( std::cout );
  std::cout << "\n";
  a << "x" << "y" << 0
    << "g" << "h" << 2
    << "b" << 0;
  a.dump( std::cout );
}

  

Best,

Kai-Uwe Bux

[toc] | [prev] | [next] | [standalone]


#7227

FromBubba <nickname@banelli.biz.invalid>
Date2011-06-29 08:28 +0000
Message-ID<Xns9F136A74974FEbubbachipsetone@130.133.4.11>
In reply to#7218
Kai-Uwe Bux's log on stardate 29 lip 2011

/snip

Thx! That's exactly what I needed. So essentially, address of class should 
be returned and simply overload operator twice (once for each data type)!

Thank you once again!

-- 
"If you lie to the compiler,
it will get its revenge."
Henry Spencer
2.718281828459045235360287471352662497757247093699959574966967627.com

[toc] | [prev] | [next] | [standalone]


#7246

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2011-06-29 14:31 -0500
Message-ID<Xns9F13DAE74AE7myfirstnameosapriee@216.196.97.131>
In reply to#7227
Bubba <nickname@banelli.biz.invalid> wrote in
news:Xns9F136A74974FEbubbachipsetone@130.133.4.11: 

> Thx! That's exactly what I needed. So essentially, address of class

A slight correction: in C++, a class is strictly a compile-time concept 
only, so it does not have an address. At run-time you have objects 
(instances of a class) which have addresses.

cheers
Paavo

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web