public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* operator<< overload question
@ 2003-12-27 17:31 Allen Wayne Best
  2003-12-27 18:01 ` Ian Lance Taylor
  0 siblings, 1 reply; 5+ messages in thread
From: Allen Wayne Best @ 2003-12-27 17:31 UTC (permalink / raw)
  To: gcc-help

hi:

i am attempting to overload the operator<< with the following function:

ostream& operator<<( ostream& o , const Sensor& s) 
{
	return o << "Name: " << endl
	<< "Port: " << s.get_port() << endl
	<< "Factor: " << s.get_conv() << endl
	<< "Raw Data: " << s.get_val() << endl
	<< "Value: " << s.get_val() * s.get_conv() << endl ;
}

in the header file, i declare this function as:

	class Sensor : public Probe
	{
	public:
		Sensor( long p = 0 , double c = 0.0 , int pd = 1 , char *nm = "") : 
			Probe( p , c , pd , nm ) { }

		...

		friend ostream& operator<<( ostream& o , const Sensor& s ) ;
	} ;

and it is used as:

		cout << "Air: " << airflow << endl ;

when i compile the code, i get the following (if i comment out the line above, 
all works well!)

g++  -g -O2   -o motor  motor.o sensor.o  
motor.o(.text+0x7cd): In function `main':
/home/best/engine-project/control-module/project/src/motor.cpp:67: undefined 
reference to `Measure::operator<<(std::basic_ostream<char, 
std::char_traits<char> >&, Measure::Sensor const&)'
collect2: ld returned 1 exit status

any suggestions are greatly appreciated! tia!

-- 
regards,
allen wayne best, esq
"your friendly neighborhood rambler owner"
"my rambler will go from 0 to 105"
Current date: 41:24:9::360:2003

Temporal anomaly

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: operator<< overload question
  2003-12-27 17:31 operator<< overload question Allen Wayne Best
@ 2003-12-27 18:01 ` Ian Lance Taylor
  2003-12-28  3:49   ` Allen Wayne Best
  0 siblings, 1 reply; 5+ messages in thread
From: Ian Lance Taylor @ 2003-12-27 18:01 UTC (permalink / raw)
  To: gcc; +Cc: gcc-help

Allen Wayne Best <gcc@atoka-software.com> writes:

> g++  -g -O2   -o motor  motor.o sensor.o  
> motor.o(.text+0x7cd): In function `main':
> /home/best/engine-project/control-module/project/src/motor.cpp:67: undefined 
> reference to `Measure::operator<<(std::basic_ostream<char, 
> std::char_traits<char> >&, Measure::Sensor const&)'
> collect2: ld returned 1 exit status
> 
> any suggestions are greatly appreciated! tia!

I suggest that you put together a complete test case in a single file,
rather than using piece-meal bits.  You haven't provided enough
information to show what has gone wrong.

In particular, the error message refers to Measure, which was not in
your sample code at all, but may be an important part of the problem.

Ian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: operator<< overload question
  2003-12-27 18:01 ` Ian Lance Taylor
@ 2003-12-28  3:49   ` Allen Wayne Best
  2003-12-28 11:03     ` Ian Lance Taylor
  0 siblings, 1 reply; 5+ messages in thread
From: Allen Wayne Best @ 2003-12-28  3:49 UTC (permalink / raw)
  To: gcc-help; +Cc: Ian Lance Taylor

ian:

good idea; here is the complete file:

#include<string>		// for string class
#include<ostream>
#include<iostream>

using namespace std ;

namespace Measure
{
	class Probe 
	{
		long	val ;		// raw value
		long	port ;		// location of the sensor
		double	conv ;		// conversion factor
		string	name ;		// name of the sensor
		int	period ;	// how often to check the value

	public:

		Probe( long p = 0 , double c = 0.0 , int pd = 1 , char *nm = "") : port(p), 
conv(c), period(pd)
		{
			name = string( nm ) ;
			val = 0 ;
		}

		~Probe() {}

		// copy constructor
		Probe( const Probe& pr ) ;
		// assignment constructor
		Probe& operator=(const Probe& pr) ;

		virtual double get() const ;
		virtual long get_val() const ;
		virtual long get_port() const ;
		virtual double get_conv() const ;
		virtual string get_name() const ;
		virtual int get_period() const ;

		virtual void set_period( int p ) ;
		virtual void set_conv( double c ) ;
	} ;

	class Sensor : public Probe
	{
	public:
		Sensor( long p = 0 , double c = 0.0 , int pd = 1 , char *nm = "") : Probe( p 
, c , pd , nm ) { }

		// copy constructor
		Sensor( const Sensor& s ) ;
		// assignment constructor
		Sensor& operator=(const Sensor& s ) ;

		~Sensor( ) { }

		double get() const ;
		long get_val() const ;
		long get_port() const ;
		double get_conv() const ;
		string get_name() const ;
		int get_period() const ;

		void set_period( int p ) ;
		void set_conv( double c ) ;
		void print( void ) ;

//		friend ostream& operator<<( ostream& o , const Sensor& s ) ;
	} ;
}

using namespace Measure ;

int main( )
{
	Sensor airflow( 0x1 , .1234 , 1 , "AIR" ) ;

	cout << "Air: " << airflow << endl ;
	cout << "Air: " ;
	airflow.print() ;
	cout << endl ;
}

double Probe::get() const
{
	return conv * val ;
}

long Probe::get_val() const
{
	return val ;
}

long Probe::get_port() const
{
	return port ;
}

double Probe::get_conv() const
{
	return conv ;
}

string Probe::get_name() const
{
	return name ;
}

int Probe::get_period() const
{
	return period ;
}

void Probe::set_period( int p )
{
	period = p ;
}

void Probe::set_conv( double c )
{
	conv = c ;
}

Probe::Probe( const Probe& pr )
{
	name = pr.name ;
	port = pr.port ;
	conv = pr.conv ;
	period = pr.period ;
	val = pr.val ;
}

Probe& Probe::operator=(const Probe& pr )
{
	if ( this != &pr )
	{
		name = pr.name ;
		port = pr.port ;
		conv = pr.conv ;
		period = pr.period ;
		val = pr.val ;
	}

	return *this ;
}

void Sensor::print( void ) 
{
	cout << "Name: " << get_name() << endl
	<< "Port: " << get_port() << endl
	<< "Factor: " << get_conv() << endl
	<< "Raw Data: " << get_val() << endl
	<< "Value: " << get() << endl ;

	return ;
}

ostream& operator<<( ostream& o , const Sensor& s) 
{
	return o << "Name: " << endl
	<< "Port: " << s.get_port() << endl
	<< "Factor: " << s.get_conv() << endl
	<< "Raw Data: " << s.get_val() << endl
	<< "Value: " << s.get_val() * s.get_conv() << endl ;
}

Sensor::Sensor( const Sensor& s ) : Probe( s )
{
}

Sensor& Sensor::operator=( const Sensor& s)
{
	if ( this != &s )
	{
		Probe::operator=( s ) ;
	}

	return *this ;
}

double Sensor::get() const
{
	return Probe::get() ;
}

long Sensor::get_val(void) const
{
	return Probe::get_val() ;
}

long Sensor::get_port() const
{
	return Probe::get_port() ;
}

double Sensor::get_conv() const
{
	return Probe::get_conv() ;
}

string Sensor::get_name(void) const
{
	return Probe::get_name() ;
}

int Sensor::get_period() const
{
	return Probe::get_period() ;
}

void Sensor::set_period( int p )
{
	Probe::set_period( p ) ;
}

void Sensor::set_conv( double c )
{
	Probe::set_conv( c ) ;
}

and the build output is:

make  all-recursive
make[1]: Entering directory `/home/best/engine-project/control-module/project'
Making all in src
make[2]: Entering directory 
`/home/best/engine-project/control-module/project/src'
source='motor.cpp' object='motor.o' libtool=no \
depfile='.deps/motor.Po' tmpdepfile='.deps/motor.TPo' \
depmode=gcc3 /bin/sh ../config/depcomp \
g++ -DHAVE_CONFIG_H -I. -I. -I..     -g -O2 -c -o motor.o `test -f 'motor.cpp' 
|| echo './'`motor.cpp
motor.cpp: In function `int main()':
motor.cpp:76: no match for `std::basic_ostream<char, std::char_traits<char> >& 
   << Measure::Sensor&' operator
/usr/include/c++/3.2.2/bits/ostream.tcc:55: candidates are: 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(std::basic_ostream<_CharT, 
   _Traits>&(*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, 
   _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:77:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(std::basic_ios<_CharT, 
   _Traits>&(*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, 
_Traits 
   = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:99:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(std::ios_base&(*)(std::ios_base&)) [with _CharT = 
char, 
   _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:171:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(long int) [with _CharT = char, _Traits = 
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:208:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = 
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:146:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(bool) [with _CharT = char, _Traits = 
   std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:104:                 std::basic_ostream<_CharT, 
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with 
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:115:                 std::basic_ostream<_CharT, 
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned 
   int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:119:                 std::basic_ostream<_CharT, 
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT 
   = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:130:                 std::basic_ostream<_CharT, 
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) 
   [with _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:234:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(long long int) [with _CharT = char, _Traits = 
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:272:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = 
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:298:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(double) [with _CharT = char, _Traits = 
   std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:145:                 std::basic_ostream<_CharT, 
   _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with 
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:323:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(long double) [with _CharT = char, _Traits = 
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:348:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(const void*) [with _CharT = char, _Traits = 
   std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:120:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, 
   _Traits>::operator<<(std::basic_streambuf<_CharT, _Traits>*) [with _CharT = 
   char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:211:                 std::basic_ostream<_CharT, 
   _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, char) [with 
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:500:                 
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, 
   _Traits>&, char) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:222:                 std::basic_ostream<char, 
   _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, signed char) 
   [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:227:                 std::basic_ostream<char, 
   _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, unsigned 
char) 
   [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:572:                 
   std::basic_ostream<_CharT, _Traits>& 
   std::operator<<(std::basic_ostream<_CharT, _Traits>&, const char*) [with 
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:622:                 
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, 
   _Traits>&, const char*) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:246:                 std::basic_ostream<char, 
   _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const signed 
   char*) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/ostream:251:                 std::basic_ostream<char, 
   _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const 
unsigned 
   char*) [with _Traits = std::char_traits<char>]
make[2]: *** [motor.o] Error 1
make[2]: Leaving directory 
`/home/best/engine-project/control-module/project/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/best/engine-project/control-module/project'
make: *** [all] Error 2

On Saturday 27 December 2003 10:00, Ian Lance Taylor pronounced:
> Allen Wayne Best <gcc@atoka-software.com> writes:
> > g++  -g -O2   -o motor  motor.o sensor.o
> > motor.o(.text+0x7cd): In function `main':
> > /home/best/engine-project/control-module/project/src/motor.cpp:67:
> > undefined reference to `Measure::operator<<(std::basic_ostream<char,
> > std::char_traits<char> >&, Measure::Sensor const&)'
> > collect2: ld returned 1 exit status
> >
> > any suggestions are greatly appreciated! tia!
>
> I suggest that you put together a complete test case in a single file,
> rather than using piece-meal bits.  You haven't provided enough
> information to show what has gone wrong.
>
> In particular, the error message refers to Measure, which was not in
> your sample code at all, but may be an important part of the problem.
>
> Ian

-- 
regards,
allen wayne best, esq
"your friendly neighborhood rambler owner"
"my rambler will go from 0 to 105"
Current date: 11:46:19::360:2003

If you push the "extra ice" button on the soft drink vending machine, you 
won't get any ice.  If you push the "no ice" button, you'll get ice, but no 
cup.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: operator<< overload question
  2003-12-28  3:49   ` Allen Wayne Best
@ 2003-12-28 11:03     ` Ian Lance Taylor
  2003-12-28 17:34       ` Allen Wayne Best
  0 siblings, 1 reply; 5+ messages in thread
From: Ian Lance Taylor @ 2003-12-28 11:03 UTC (permalink / raw)
  To: gcc; +Cc: gcc-help

Allen Wayne Best <gcc@atoka-software.com> writes:

> good idea; here is the complete file:

Well, this example doesn't compile because you commented out the
declaration of the relevant operator>>:

> //		friend ostream& operator<<( ostream& o , const Sensor& s ) ;

When I uncomment that line, the file compiles.

When I try to link it, I get

foo1.o(.text+0x6b): undefined reference to `Measure::operator<<(std::ostream&, Measure::Sensor const&)'

That's because of this line:

> ostream& operator<<( ostream& o , const Sensor& s) 

That defines operator<<, not Measure::operator<<.  Your friend
declaration was inside namespace Measure.

When I change the function definition to:

ostream& Measure::operator<<( ostream& o , const Sensor& s) 

then the file compiles and links.


Alternatively, if I add these lines at the top:

namespace Measure { class Sensor; }
extern ostream& operator<<( ostream& o , const Measure::Sensor& s );

and then change the friend declaration to

		friend ostream& ::operator<<( ostream& o , const Sensor& s ) ;

then the file compiles and links.

Ian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: operator<< overload question
  2003-12-28 11:03     ` Ian Lance Taylor
@ 2003-12-28 17:34       ` Allen Wayne Best
  0 siblings, 0 replies; 5+ messages in thread
From: Allen Wayne Best @ 2003-12-28 17:34 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-help

ian:

thanks so much for your assistance.

On Sunday 28 December 2003 03:03, Ian Lance Taylor pronounced:
> Allen Wayne Best <gcc@atoka-software.com> writes:
> > good idea; here is the complete file:
>
> Well, this example doesn't compile because you commented out the
>
> declaration of the relevant operator>>:
> > //		friend ostream& operator<<( ostream& o , const Sensor& s ) ;
>
> When I uncomment that line, the file compiles.
>
> When I try to link it, I get
>
> foo1.o(.text+0x6b): undefined reference to
> `Measure::operator<<(std::ostream&, Measure::Sensor const&)'
>
> That's because of this line:
> > ostream& operator<<( ostream& o , const Sensor& s)
>
> That defines operator<<, not Measure::operator<<.  Your friend
> declaration was inside namespace Measure.
>
> When I change the function definition to:
>
> ostream& Measure::operator<<( ostream& o , const Sensor& s)
>
> then the file compiles and links.
>
>
> Alternatively, if I add these lines at the top:
>
> namespace Measure { class Sensor; }
> extern ostream& operator<<( ostream& o , const Measure::Sensor& s );
>
> and then change the friend declaration to
>
> 		friend ostream& ::operator<<( ostream& o , const Sensor& s ) ;
>
> then the file compiles and links.
>
> Ian

-- 
regards,
allen wayne best, esq
"your friendly neighborhood rambler owner"
"my rambler will go from 0 to 105"
Current date: 22:33:9::361:2003

An egghead is one who stands firmly on both feet, in mid-air, on both
sides of an issue.
		-- Homer Ferguson

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2003-12-28 17:34 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-12-27 17:31 operator<< overload question Allen Wayne Best
2003-12-27 18:01 ` Ian Lance Taylor
2003-12-28  3:49   ` Allen Wayne Best
2003-12-28 11:03     ` Ian Lance Taylor
2003-12-28 17:34       ` Allen Wayne Best

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).