[c++] 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

This question is related to c++ pass-by-reference default-value

The answer is


There is also rather dirty trick for this:

virtual const ULONG Write(ULONG &&State = 0, bool sequence = true);

In this case you have to call it with std::move:

ULONG val = 0;
Write(std::move(val));

It is only some funny workaround, I totally do not recommend it using in real code!


virtual const ULONG Write(ULONG &State = 0, bool sequence = true);

The answer is quite simple and I am not so good on explaining but if you want to pass a default value to a non-const parameter which probably will be modified in this function is to use it like this:

virtual const ULONG Write(ULONG &State = *(ULONG*)0, bool sequence =
> true);

void f(const double& v = *(double*) NULL)
{
  if (&v == NULL)
    cout << "default" << endl;
  else
    cout << "other " << v << endl;
}

void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);

You cannot use a constant literal for a default parameter for the same reason you cannot use one as a parameter to the function call. Reference values must have an address, constant references values need not (ie they can be r-values or constant literals).

int* foo (int& i )
{
   return &i;
}

foo(0); // compiler error.

const int* bar ( const int& i )
{
   return &i;
}

bar(0); // ok.

Ensure that you're default value has an address and you're fine.

int null_object = 0;

int Write(int &state = null_object, bool sequence = true)
{
   if( &state == &null_object )
   {
      // called with default paramter
      return sequence? 1: rand();
   }
   else
   {
      // called with user parameter
      state += sequence? 1: rand();
      return state;
   }
}

I've used this pattern a few times where I had a parameter that could be a variable or null. The regular approach is to have the user pass in a pointer this is case. They pass in a NULL pointer if they don't want you to fill in the value. I like to null object approach. It makes the callers life easier without terribly complicating the callee code.


No, it's not possible.

Passing by reference implies that the function might change the value of the parameter. If the parameter is not provided by the caller and comes from the default constant, what is the function supposed to change?


Another way could be the following:

virtual const ULONG Write(ULONG &State, bool sequence = true);

// wrapper
const ULONG Write(bool sequence = true)
{
   ULONG dummy;
   return Write(dummy, sequence);
}

then the following calls are possible:

ULONG State;
object->Write(State, false); // sequence is false, "returns" State
object->Write(State); // assumes sequence = true, "returns" State
object->Write(false); // sequence is false, no "return"
object->Write(); // assumes sequence = true, no "return"

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);

I think not, and the reason is that default values are evaluated to constants and values passed by reference must be able to change, unless you also declare it to be constant reference.


Define 2 overload functions.

virtual const ULONG Write(ULONG &State, bool sequence = true);

virtual const ULONG Write(bool sequence = true)
{
    int State = 0;
    return Write(State, sequence);
}

I have a workaround for this, see the following example on default value for int&:

class Helper
{
public:
    int x;
    operator int&() { return x; }
};

// How to use it:
void foo(int &x = Helper())
{

}

You can do it for any trivial data type you want, such as bool, double ...


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;
}

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.


In case of OO... To say that a Given Class has and "Default" means that this Default (value) must declared acondingly an then may be usd as an Default Parameter ex:

class Pagination {
public:
    int currentPage;
    //...
    Pagination() {
        currentPage = 1;
        //...
    }
    // your Default Pagination
    static Pagination& Default() {
        static Pagination pag;
        return pag;
    }
};

On your Method ...

 shared_ptr<vector<Auditoria> > 
 findByFilter(Auditoria& audit, Pagination& pagination = Pagination::Default() ) {

This solutions is quite suitable since in this case, "Global default Pagination" is a single "reference" value. You will also have the power to change default values at runtime like an "gobal-level" configuration ex: user pagination navigation preferences and etc..


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.


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.


It's possible with const qualifier for State:

virtual const ULONG Write(const ULONG &State = 0, bool sequence = true);

Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to pass-by-reference

Passing an integer by reference in Python Does JavaScript pass by reference? Object passed as parameter to another class, by value or reference? change values in array when doing foreach Call-time pass-by-reference has been removed C++ pass an array by reference Passing Objects By Reference or Value in C# Pass variables by reference in JavaScript JavaScript by reference vs. by value How to do the equivalent of pass by reference for primitives in Java

Examples related to default-value

How to set a default value in react-select How to set default values in Go structs What is the default value for Guid? CURRENT_DATE/CURDATE() not working as default DATE value Entity Framework 6 Code first Default value Default values and initialization in Java Python argparse: default value or specified value Javascript Get Element by Id and set the value Why is the default value of the string type null instead of an empty string? SQL Column definition : default value and not null redundant?