Есть две причины для передачи аргумента по ссылке: (1) для производительности (в этом случае вы хотите передать по ссылке const) и (2), потому что вам нужна возможность изменять значение аргумента внутри функции.
Я очень сомневаюсь, что использование unsigned long на современных архитектурах слишком сильно замедляет вас. Итак, я предполагаю, что вы собираетесь изменить значение Stateвнутри метода. Компилятор жалуется, потому что константа 0не может быть изменена, так как это rvalue («не-lvalue» в сообщении об ошибке) и неизменяемое ( constв сообщении об ошибке).
Проще говоря, вам нужен метод, который может изменить переданный аргумент, но по умолчанию вы хотите передать аргумент, который не может измениться.
Другими словами, не constссылки должны относиться к фактическим переменным. Значение по умолчанию в функции signature ( 0) не является реальной переменной. У вас та же проблема, что и:
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
Если вы на самом деле не собираетесь вносить изменения Stateв метод, вы можете просто изменить его на const ULONG&. Но вы не получите от этого большого выигрыша в производительности, поэтому я бы порекомендовал изменить его на нереференсный ULONG. Я заметил, что вы уже возвращаете a ULONG, и у меня есть скрытое подозрение, что его значением является значение Stateпосле любых необходимых изменений. В этом случае я бы просто объявил метод так:
// returns value of State
virtual ULONG Write(ULONG State = 0, bool sequence = true);
Конечно, я не совсем понимаю, что вы пишете и куда. Но это другой вопрос в другой раз.