There are two reasons to pass an argument by reference: (1) for performance (in which case you want to pass by const reference) and (2) because you need the ability to change the value of the argument inside the function.
I highly doubt that passing an unsigned long on modern architectures is slowing you down too much. So I'm assuming that you're intending to change the value of State
inside the method. The compiler is complaining because the constant 0
cannot be changed, as it's an rvalue ("non-lvalue" in the error message) and unchangeable (const
in the error message).
Simply put, you want a method that can change the argument passed, but by default you want to pass an argument that can't change.
To put it another way, non-const
references have to refer to actual variables. The default value in the function signature (0
) is not a real variable. You're running into the same problem as:
struct Foo {
virtual ULONG Write(ULONG& State, bool sequence = true);
};
Foo f;
ULONG s = 5;
f.Write(s); // perfectly OK, because s is a real variable
f.Write(0); // compiler error, 0 is not a real variable
// if the value of 0 were changed in the function,
// I would have no way to refer to the new value
If you don't actually intend to change State
inside the method you can simply change it to a const ULONG&
. But you're not going to get a big performance benefit from that, so I would recommend changing it to a non-reference ULONG
. I notice that you are already returning a ULONG
, and I have a sneaky suspicion that its value is the value of State
after any needed modifications. In which case I would simply declare the method as so:
// returns value of State
virtual ULONG Write(ULONG State = 0, bool sequence = true);
Of course, I'm not quite sure what you're writing or to where. But that's another question for another time.