473,725 Members | 2,169 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Overloading unary minus for use in function calls

I would like to overload the unary minus operator so that I can negate
an instance of a class and pass that instance to a function without
creating an explicit temporary variable. Here is an example:

#include <iostream>
using namespace std;

class Object
{
public:
int number;
Object(int value);
const Object operator- ();
//friend const Object operator- (const Object& o);

};

Object::Object( int value) :
number (value)
{}

const Object Object::operato r- ()
{
cout << "using class minus" << endl;
number = -number;
return *this;
}
/*
const Object operator- (const Object& o)
{
cout << "using friend minus" << endl;
return Object(-o.number);
}*/

void useAnObject(Obj ect& o)
{
cout << "using object with number: " << o.number << endl;
}

int main(int argc, char* argv[])
{
Object a(4);
useAnObject(-a); // does not work but would like it to
//Object b = -a; // works, but I don't like it
//useAnObject(b);
}

When I compile this, I get the following errors (gcc 4.0.1):
c++ unaryminus.cpp -o unaryminus
unaryminus.cpp: In function 'int main(int, char**)':
unaryminus.cpp: 39: error: invalid initialization of non-const reference
of type 'Object&' from a temporary of type 'const Object'
unaryminus.cpp: 31: error: in passing argument 1 of 'void
useAnObject(Obj ect&)'

I have tried various combinations of returning void, returning const
Object, returning non-const Object, returning reference to Object, etc,
but i get similar errors. Is there a way to do this?

-Matthew

Dec 20 '06 #1
6 2588
IR
Matthew Cook wrote:
I would like to overload the unary minus operator so that I can
negate an instance of a class and pass that instance to a function
without creating an explicit temporary variable. Here is an
example:

#include <iostream>
using namespace std;

class Object
{
public:
int number;
Object(int value);
const Object operator- ();
operator -() should not modify the object, so it should be declared
const.
Also, are you sure you are willing to return a const Object?

I'd rather declare it:

Object operator -() const;

//friend const Object operator- (const Object& o);

};

Object::Object( int value) :
number (value)
{}

const Object Object::operato r- ()
{
cout << "using class minus" << endl;
number = -number;
return *this;
}
Object Object::operato r -() const
{
cout << "Object::operat or -()" << endl;
return Object(-number);
}
/*
const Object operator- (const Object& o)
{
cout << "using friend minus" << endl;
return Object(-o.number);
}*/

void useAnObject(Obj ect& o)
{
cout << "using object with number: " << o.number << endl;
}

int main(int argc, char* argv[])
{
Object a(4);
useAnObject(-a); // does not work but would like it to
It works now :p
//Object b = -a; // works, but I don't like it
//useAnObject(b);
}

When I compile this, I get the following errors (gcc 4.0.1):
c++ unaryminus.cpp -o unaryminus
unaryminus.cpp: In function 'int main(int, char**)':
unaryminus.cpp: 39: error: invalid initialization of non-const
reference of type 'Object&' from a temporary of type 'const
Object' unaryminus.cpp: 31: error: in passing argument 1 of 'void
useAnObject(Obj ect&)'
The compiler said it: your operator -() returned a const Object,
while useAnObject expected an Object&. How could the compiler cast
the const away?
Cheers,
--
IR
Dec 20 '06 #2
Matthew Cook wrote:
>
void useAnObject(Obj ect& o)
{
cout << "using object with number: " << o.number << endl;
}

int main(int argc, char* argv[])
{
Object a(4);
useAnObject(-a); // does not work but would like it to
//Object b = -a; // works, but I don't like it
//useAnObject(b);
}

When I compile this, I get the following errors (gcc 4.0.1):
c++ unaryminus.cpp -o unaryminus
unaryminus.cpp: In function 'int main(int, char**)':
unaryminus.cpp: 39: error: invalid initialization of non-const reference
of type 'Object&' from a temporary of type 'const Object'
unaryminus.cpp: 31: error: in passing argument 1 of 'void
useAnObject(Obj ect&)'

I have tried various combinations of returning void, returning const
Object, returning non-const Object, returning reference to Object, etc,
but i get similar errors. Is there a way to do this?
The compiler is telling you that you can't bind a temporary object to a
non const reference. You are also attempting to assign a cost reference
to a reference.

void useAnObject( const Object& o)

will see you right.

--
Ian Collins.
Dec 20 '06 #3
Matthew Cook wrote:
I would like to overload the unary minus operator so that I can negate
an instance of a class and pass that instance to a function without
creating an explicit temporary variable. Here is an example:

#include <iostream>
using namespace std;

class Object
{
public:
int number;
Object(int value);
const Object operator- ();
Why are you returning a "const Object" ? You may as well return an Object.

I also suspect that "- OBJ" should not change OBJ. So operator- should
be a const function.

i.e.
Object operator- () const;
//friend const Object operator- (const Object& o);

};

Object::Object( int value) :
number (value)
{}

const Object Object::operato r- ()
Object operator- () const
{
cout << "using class minus" << endl;
number = -number;
Can't be messing with number.
return *this;
Return a different Object.

return Object( -number );
}
/*
const Object operator- (const Object& o)
{
cout << "using friend minus" << endl;
return Object(-o.number);
}*/

void useAnObject(Obj ect& o)
If you want to accept references to temporaries as arguments, you must
make them "const" temporaries.

void useAnObject(con st Object& o)

{
cout << "using object with number: " << o.number << endl;
}

int main(int argc, char* argv[])
{
Object a(4);
useAnObject(-a); // does not work but would like it to
//Object b = -a; // works, but I don't like it
//useAnObject(b);
}

When I compile this, I get the following errors (gcc 4.0.1):
c++ unaryminus.cpp -o unaryminus
unaryminus.cpp: In function 'int main(int, char**)':
unaryminus.cpp: 39: error: invalid initialization of non-const reference
of type 'Object&' from a temporary of type 'const Object'
unaryminus.cpp: 31: error: in passing argument 1 of 'void
useAnObject(Obj ect&)'

I have tried various combinations of returning void, returning const
Object, returning non-const Object, returning reference to Object, etc,
but i get similar errors. Is there a way to do this?
#include <iostream>
using namespace std;

class Object
{
public:
int number;
Object(int value);
Object operator- () const;
//friend const Object operator- (const Object& o);

};

Object::Object( int value) :
number (value)
{}

Object Object::operato r- () const
{
cout << "using class minus" << endl;
return Object( -number );
}
/*
const Object operator- (const Object& o)
{
cout << "using friend minus" << endl;
return Object(-o.number);
}*/

void useAnObject(con st Object& o)
{
cout << "using object with number: " << o.number << endl;
}

int main(int argc, char* argv[])
{
Object a(4);
useAnObject(-a); // does not work but would like it to
//Object b = -a; // works, but I don't like it
//useAnObject(b);
}

>
-Matthew
Dec 20 '06 #4
IR
Ian Collins wrote:
The compiler is telling you that you can't bind a temporary object
to a non const reference.
Damn, I missed this one... and VC8 didn't even blink on it :-/
Cheers,
--
IR
Dec 20 '06 #5
Thanks to everyone for the quick reply.

I was returning const Objects on the advice of Effective C++'s Item 3
(top of pg 13, possibly over-liberally applied in this case).

I guess what I was really trying for was a function to negate the
object in place rather than making a copy. However the more I look at
things, the less this seems to fit with the expected behavior of
overloading this operator. I think an explicit negate function might
be more appropriate.

For those who may find their way across this post in the future, IR's
raises a good point in the prev post. This seem to only work when the
temporary object created is passed as constant regardless of the return
type of the operator-. It seems to be the case that implicit temporary
variables like this are always const (perhaps someone can quote chapter
and verse from the standard.) However, I was sure I'd done this on
VC++ in the past. It appears the case may have changed. Google
provides this tidbit from microsoft:

http://msdn2.microsoft.com/en-US/lib...dc(vs.80).aspx

Many Thanks,
-Matthew

Dec 20 '06 #6
IR
Matthew Cook wrote:
For those who may find their way across this post in the future,
IR's raises a good point in the prev post.
I did not raise that issue. Ian Collins and Gianni Mariani did. I
was only a victim of both my compiler and my thoughtlessness . ;-)
This seem to only work
when the temporary object created is passed as constant regardless
of the return type of the operator-. It seems to be the case that
implicit temporary variables like this are always const (perhaps
someone can quote chapter and verse from the standard.) However,
I was sure I'd done this on VC++ in the past. It appears the case
may have changed. Google provides this tidbit from microsoft:

http://msdn2.microsoft.com/en-US/lib...dc(vs.80).aspx
Although I can't quote the relevant paragraph from the standard, the
link you provided is right (in theory, not in practice).

VC8 didn't generate an error (as it should, to my understanding)
either with the code I posted earlier, nor with the following code:

class C {};
void f(C & c) {}

int main()
{
f(C());
}

(of course, Comeau correctly identifies the error)
FWIW, I figured out that VC8 generates this error only when M$
language "extensions " are disabled. Otherwise, it only issues a
warning when at maximum warning level (4).

What got me wrong is that I always keep those extensions enabled
(because when disabled, Windows headers simply don't compile), and
that my test project wasn't at warning level 4 contrary to my habit.

I guess this will teach me to *always* double-check that my compiler
options are the strictest possible... :-)
Cheers,
--
IR
Dec 20 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
4720
by: Terje Slettebø | last post by:
To round off my trilogy of "why"'s about PHP... :) If this subject have been discussed before, I'd appreciate a pointer to it. I again haven't found it in a search of the PHP groups. The PHP manual mentions "overloading" (http://no.php.net/manual/en/language.oop5.overloading.php), but it isn't really overloading at all... Not in the sense it's used in other languages supporting overloading (such as C++ and Java). As one of the...
3
3902
by: Carlos Ribeiro | last post by:
I was checking the Prolog recipe in the Cookbook: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/303057 It's a clever implementation that explores some aspects of Python that I wasn't aware of. One of them is the unary plus operator, that calls the __pos__ method. It's something that can be highly useful in my own experiments with the use of classes as a tool for generic declarative descriptions of objects -- UI forms,...
6
8790
by: Andrew Ward | last post by:
Hi All, I tried to compile the following line: pair<long, ulong> cr3(make_pair(-2147483648L, 2147483647)); but get this error: unary minus applied to unsigned type, result still unsigned. But in my c++ book is says that the postfix L forces the integer to be signed.
2
2369
by: Javier Estrada | last post by:
1. For types smaller than int, when I compile: class MyClass { static void Main(string args) { x = 10; y = -x; }
13
5092
by: Marc | last post by:
Hi, I've been lurking on clc for a few months now, and want to start by thanking the regulars here for opening my eyes to a whole new dimension of "knowing c". Considering I had never even touched the standards a year ago, though I graduated in embedded SW development... Anyway, to the problem at hand: I've stumbled upon the following construct at work recently, and cannot really make up my mind about the standard's take on the matter.
5
3625
by: Jerry Fleming | last post by:
As I am newbie to C++, I am confused by the overloading issues. Everyone says that the four operators can only be overloaded with class member functions instead of global (friend) functions: (), , ->, =. I wonder why there is such a restriction. Some tutorials say that 'new' and 'delete' can only be overloaded with static member functions, others say that all overloading function should be non-static. Then what is the fact, and why? ...
28
5077
by: dspfun | last post by:
I'm trying to get a good understanding of how unary operators work and have some questions about the following test snippets. int *p; ~!&*++p--; It doesn't compile, why? The problem seems to be the ++, the compiler says: "Error: invalid l-value in increment". int i = 10; ~!*&i++;
19
2295
by: Jess | last post by:
Hello, After seeing some examples about operator overloading, I'm still a bit confused about the general syntax. The following is what I think, not sure whether it's correct. 1. For a unary operator that's a member of a class, its form is usually "operatorP()" (where P is the operator's name).
8
2973
by: Wayne Shu | last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition). When I read chapter 11 Operator Overloading, I have two questions. 1. In subsection 11.2.2 paragraph 1, B.S. wrote "In particular, operator =, operator, operator(), and operator-must be nonstatic member function; this ensures that their first operands will be lvalues". I know that these operators must be nonstatic member functions, but why this ensure their first operands will...
0
8888
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8752
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9401
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9257
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9176
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6702
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6011
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4784
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3221
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.