Is there a case where this would be valid C++ code?
int main()
{
int k = 0;
++f(k);
}
Yes, if f
returns a reference.
int main()
{
int k = 0;
++f(k);
}
int & f(int & k) {
return k;
}
Edit:
As pointed out in the comments, there is another possibility: you can call ++f(k)
, if f
returns a class type and it has the ++operator(void)
overloaded as a member function.
Well, for one, it would work if you preceded that code with:
#define f
but that's not applying the increment operator to a function, as you seem to desire in your title. If you try to apply it to a function as below:
int f (int x) { return x + 1; }
you will get the error:
error: lvalue required as increment operand
because the returned value is not an lvalue
(obviously). You can return a reference to a variable which can then be incremented thus:
#include <iostream>
int xyzzy = 42;
int & f(int x) { return xyzzy; }
int main() {
int k = 0;
++f(k);
std::cout << xyzzy << '\n';
return 0;
}
This works because the returned reference references the xyzzy
variable; it outputs:
43
The function f
will be run before the ++ pre-operator, This is due to precedence of operators. You are not incrementing the function but the value it returns. So this code would only be valid if the value returned by f(k)
can be incremented.
In short, yes, this code is valid in a lot of cases (when the object f returns is not const and can be incremented).
f()
could return a reference that you want to increase after returning from the function. for example:
int someGlobal;
int& f(int k) {
return someGlobal;
}
Though it is wrong in many ways [designically speaking]
In the obvious case that f
has the signature int f(int)
or some equivalent, no: you cannot use ++
on a temporary. It would not even compile.
If it's made to compile by some other trick (such as f
returning a reference) then there's still the matter that code like this is an example of what to avoid.
So it all depends on what you mean by valid: it can be valid as the compiler is concerned, but IMO it's not valid in the sense that I could read this code and not have some choice things to say about the author.
Sure: Suppose you want one more than a square number:
int & square(int & n)
{
n = n * n;
return n;
}
Now you can say,
int k;
++f(k);
and it has the same effect as int k = 0 * 0 + 1;
. The example is not so exciting for 0
, but makes sense in general. It's questionable whether it is good style to have a function both mutate the argument and return a reference to it, but the pre-increment has the same semantics, and you can write ++square(++square(k))
if you like.
When f returns an int&, for example.