When overloading the postfix operator, I can do something simple like
Class Foo
{
private:
int someBS;
public:
//declaration of pre &postfix++
Foo operator++();
//rest of class not shown
};
Prefix doesn't need to take any parameters, so when I define it, something like
Foo Foo::operator()
{
someBS ++;
return *this;
}
and it makes perfect sense to me.
When I go to define the postfix overload I have to include a dummy int parameter
Foo Foo::operator++(int)
{
Foo temp = *this;
someBS ++;
return temp;
}
My question is why? I don't ever use it in the method. The prefix operator doesn't require one. The postfix returning the temp value is not dependent on the dummy parameter. I know that if I want to overload a postfix operator that's how it's done, I just want to know the reason behind.
The dummy parameter is simply there to distinguish between the postfix and prefix operators. The name ++ or -- is the same in both cases, so there has to be some way to specify which one you're defining. Adding a dummy parameter is perhaps not elegant, but any alternatives would probably have required inventing new syntax (perhaps a postfix keyword, which would break code that uses postfix as an identifier).
Citing C++reference here:
Prefix versions of the built-in operators return references and postfix versions return values, and typical user-defined overloads follow the pattern so that the user-defined operators can be used in the same manner as the built-ins.
Explaining this logically:
int a = 3;
int b = 0;
int c = a + ++b;
int d = a++ + b;
In the third line, ++b gives you a reference to the updated value; in the fourth line, that's not possible: a has to be increased, so a value-copy is made, and added to b. That dictates different semantics for the operators.
In fact, just to avoid having another operator name:
The int parameter is a dummy parameter used to differentiate between prefix and postfix versions of the operators. When the user-defined postfix operator is called, the value passed in that parameter is always zero, although it may be changed by calling the operator using function call notation (e.g., a.operator++(2) or operator++(a, 2)).
To quote cppreference:
The int parameter is a dummy parameter used to differentiate between prefix and postfix versions of the operators.
The quote says it all, because how else would you differentiate prefix and postfix?
Let's just say that you don't need the int parameter, then the prefix (Foo operator++()) and postfix (Foo operator++()) would be exactly the same! How would the compiler know which one you meant? That's why there is this dummy int parameter.
Related
When overloading the postfix operator, I can do something simple like
Class Foo
{
private:
int someBS;
public:
//declaration of pre &postfix++
Foo operator++();
//rest of class not shown
};
Prefix doesn't need to take any parameters, so when I define it, something like
Foo Foo::operator()
{
someBS ++;
return *this;
}
and it makes perfect sense to me.
When I go to define the postfix overload I have to include a dummy int parameter
Foo Foo::operator++(int)
{
Foo temp = *this;
someBS ++;
return temp;
}
My question is why? I don't ever use it in the method. The prefix operator doesn't require one. The postfix returning the temp value is not dependent on the dummy parameter. I know that if I want to overload a postfix operator that's how it's done, I just want to know the reason behind.
The dummy parameter is simply there to distinguish between the postfix and prefix operators. The name ++ or -- is the same in both cases, so there has to be some way to specify which one you're defining. Adding a dummy parameter is perhaps not elegant, but any alternatives would probably have required inventing new syntax (perhaps a postfix keyword, which would break code that uses postfix as an identifier).
Citing C++reference here:
Prefix versions of the built-in operators return references and postfix versions return values, and typical user-defined overloads follow the pattern so that the user-defined operators can be used in the same manner as the built-ins.
Explaining this logically:
int a = 3;
int b = 0;
int c = a + ++b;
int d = a++ + b;
In the third line, ++b gives you a reference to the updated value; in the fourth line, that's not possible: a has to be increased, so a value-copy is made, and added to b. That dictates different semantics for the operators.
In fact, just to avoid having another operator name:
The int parameter is a dummy parameter used to differentiate between prefix and postfix versions of the operators. When the user-defined postfix operator is called, the value passed in that parameter is always zero, although it may be changed by calling the operator using function call notation (e.g., a.operator++(2) or operator++(a, 2)).
To quote cppreference:
The int parameter is a dummy parameter used to differentiate between prefix and postfix versions of the operators.
The quote says it all, because how else would you differentiate prefix and postfix?
Let's just say that you don't need the int parameter, then the prefix (Foo operator++()) and postfix (Foo operator++()) would be exactly the same! How would the compiler know which one you meant? That's why there is this dummy int parameter.
I understand how to make prefix and postfix incrementers. Within my class DoStuff, I have:
// Prefix; returns the incremented value
friend const DoStuff& operator++(DoStuff& a);
// Postfix: returns the incremented value
friend const DoStuff operator++(DoStuff& a, int);
and outside the class, I have
const DoStuff& operator++(DoStuff& a){
a.num++;
return a;
}
const DoStuff operator++(DoStuff& a, int){
DoStuff before(a.num);
a.num++;
return before;
}
for the prefix and postfix incrementers respectively. What I don't understand is how C++ knows that the former is represented by ++a and the latter a++. As far as I can tell, the prefix incrementer references the address & and that somehow means that the ++ operator symbol should come before it.
Also, I'm not too sure why the postfix needs an int variable.
When the compiler reads your source code, it can figure out whether you've used a prefix or a postfix. Very simple: either the ++ comes up before or after some object.
Then the compiler will generate code to call the right function. But what's the name of that function? The people that designed C++ decided to make the function name for overloaded operators operator followed by the operator you're overloading (++, --, = etc), like operator*, operator-, etc.
But the problem now is that both prefix and postfix increment operators are named operator++. How do you differentiate between them? When you encounter ++var and var++, the compiler generates code to call operator++ for both of them, but you don't want that because now you can't differentiate between the definitions between a postfix and a prefix increment operator.
To solve this, the same language designers added a dummy parameter, int. This way, the compiler can call operator++(0), or operator++(42) (or whatever number you feel like, it's not important. It's a dummy parameter) when it encounters a postfix ++, and just an operator++() when it encounters a prefix. The parameter is just there for differentiation.
All in all, this is a language design problem. When it comes to design decisions, naturally, there must've been other solutions (like naming them operator_preinc() and operator_postinc()), but this is what the designers of C++ chose to go with. They could have their reasons, or it could be arbitrarily chosen because maybe all other options weigh about the same.
I was looking at an iterator class for a linked list and saw this operator overloading and didn't really understand what was going on. I was under the impression that 'int' always has to be declared with a variable name?
void operator++(int)
{
assert(m_node != NULL);
m_node = m_node->m_next;
}
void operator--(int)
{
assert(m_node != NULL);
m_node = m_node->m_prev;
}
Parameter names are always optional. However, the int in this case is special as it denotes this is a postfix operator meaning you are able to do list++ and list--.
Reference: http://en.cppreference.com/w/cpp/language/operators
You can always leave out a parameter name if you want to. If you do that in a normal function definition, that means that an argument must still be provided to the function, but the function doesn't use it:
void f(int) // unnamed parameter
{
// can't use the parameter without a name
}
f(); // ERROR: wants an int
f(42); // OK: takes an int (but ignores it)
In the case of the increment and decrement operators, an unused int parameter is the magic that indicates that this is the postfix operator, x++, not the prefix operator, ++x, which has no parameters.
Because you have two ++ operators, it is a special syntax to differentiate them between post- and pre- incrementation.
void operator++(int)
means postincrementation
void operator++()
means preincrementation
So in your case, you first return, then increase.
void operator++(int)
This means post increment operator. int is just a dummy variable to distinguish it from pre-increment operator. Compiler would pass 0 in its place when calling post increment operator.
As I know here is the way to overload the post-increment operator:
const MyClass& MyClass::operator++(int);
Why does it have int as an argument?
D&E, §11.5.3:
I conisdered the obvious solution, adding the keywords prefix and postfix to C++ [ ... ]
However I received the usual howl of outrage from people who dislike new keywords. Several alternatives that did not involve new keywords were suggested. For example:
class Ptr_to_X {
X ++operator(); // prefix ++
X operator++(); // postfix ++
};
or
class Ptr_to_X {
X& operator++(); // postfix because it
// returns a reference
x operator++(); // prefix because it
// doesn't return a reference
};
I considered the former too cute and the latter too subtle. Finally I settled on:
class Ptr_to_X {
X operator++(); // prefix: no argument
X operator++(int); // postfix: because of the argument
};
This may be too cute and too subtle, but it works, requires no new syntax, and has a logic to the madness. Other unary operators are prefix and take no arguments when defined as member functions. The "odd" and unused dummy int argument is used to indicate the odd postfix operators. In other words, in the postfix case, ++ comes between the first (real) operand and the second (dummy) argument and is thus postfix.
These explanations are needed because the mechanism is unique, and therefore a bit of a wart. Given a choice I would probably have introduced the prefix and postfix keywords, but that didn't appear feasible at the time.
This is to distinguish between prefix increment and postfix increment operators.
For completeness, this is set out in §13.5.7 in both the C++03 and the C++11 standards.
So I'm in a basic programming II class. We have to create a program that makes 4 different functions that will change the way an operator works. I've looked up multiple examples and sets of text that display how to do this, but I cannot make which way of what any of the code means. To me something like this should work.
int operator++()
{
variableA--;
}
To me, this says if you encounter a ++, then -- from the variable, now obvious it doesn't work like this. All the examples I've found create their own data type. Is there a way to overload an operator using an int or a double?
All the examples create their own data type since this is one of the rules for operator overloading: An overloaded operator must work on at least one user-defined type.
Even if you could overload ++ for integers, the compiler wouldn't know which one to use -- your version or the regular version; it would be ambiguous.
You seem to think of operators as single functions, but each overload is a completely separate function differentiated by its function signature (type and sometimes number of arguments), while having the same operator symbol (this is the definition of "overloading").
So, you can't overload ++ to always do something different; this would really be operator overriding, which C++ doesn't allow.
You can define ++ for a type you've created though:
class MyType {
public:
int value;
};
MyType const& operator++(MyType& m) { // Prefix
++m.value;
return m;
}
const MyType operator++(MyType& m, int) { // Postfix (the 'int' is just to differentiate it from the prefix version)
MyType temp = m;
++m.value;
return temp;
}
int main() {
MyType m;
m.value = 0;
m++; // Not m.value++
cout << m.value; // Prints 1
}
Note that this set of ++ operators was defined outside of the MyType class, but could have been defined inside instead (they would gain access to non-public members that way), though their implementations would be a little different.
You can't overload operators of built-in types. (Well, technically you can overload things like "int + MyClass" - but not when both sides are built-in types)
Take a look at How can I overload the prefix and postfix forms of operators ++ and --?