Default value to a parameter while passing by reference in C++
Is it possible to give a default value to a parameter of a function while we are passing the parameter by reference. in C++
For example, when I try to declare a function like:
virtual const ULONG Write(ULONG &State = 0, bool sequence = true);
When I do this it gives an error:
error C2440: 'default argument' : cannot convert from 'const int' to 'unsigned long &' A reference that is not to 'const' cannot be bound to a non-lvalue
Solution 1:
You can do it for a const reference, but not for a non-const one. This is because C++ does not allow a temporary (the default value in this case) to be bound to non-const reference.
One way round this would be to use an actual instance as the default:
static int AVAL = 1;
void f( int & x = AVAL ) {
// stuff
}
int main() {
f(); // equivalent to f(AVAL);
}
but this is of very limited practical use.
Solution 2:
It has been said in one of the direct comments to your answer already, but just to state it officially. What you want to use is an overload:
virtual const ULONG Write(ULONG &State, bool sequence);
inline const ULONG Write()
{
ULONG state;
bool sequence = true;
Write (state, sequence);
}
Using function overloads also have additional benefits. Firstly you can default any argument you wish:
class A {};
class B {};
class C {};
void foo (A const &, B const &, C const &);
void foo (B const &, C const &); // A defaulted
void foo (A const &, C const &); // B defaulted
void foo (C const &); // A & B defaulted etc...
It is also possible to redefine default arguments to virtual functions in derived class, which overloading avoids:
class Base {
public:
virtual void f1 (int i = 0); // default '0'
virtual void f2 (int);
inline void f2 () {
f2(0); // equivalent to default of '0'
}
};
class Derived : public Base{
public:
virtual void f1 (int i = 10); // default '10'
using Base::f2;
virtual void f2 (int);
};
void bar ()
{
Derived d;
Base & b (d);
d.f1 (); // '10' used
b.f1 (); // '0' used
d.f2 (); // f1(int) called with '0'
b.f2 (); // f1(int) called with '0
}
There is only one situation where a default really needs to be used, and that is on a constructor. It is not possible to call one constructor from another, and so this technique does not work in that case.
Solution 3:
There still is the old C way of providing optional arguments: a pointer that can be NULL when not present:
void write( int *optional = 0 ) {
if (optional) *optional = 5;
}
Solution 4:
This little template will help you:
template<typename T> class ByRef {
public:
ByRef() {
}
ByRef(const T value) : mValue(value) {
}
operator T&() const {
return((T&)mValue);
}
private:
T mValue;
};
Then you'll be able to:
virtual const ULONG Write(ULONG &State = ByRef<ULONG>(0), bool sequence = true);