Tutorial :How do I use an int& parameter with a default value?



Question:

I have to add a default int& argument (Eg iNewArgument) to an existing function definition in a header file:

What is the syntax to initialize the last argument to make it take a default value?

..  virtual int ExecNew      (int& param1, int& RowIn,int& RowOut, char* Msg = '0',               bool bDebug=true, int& iNewArgument = NULL ) = 0 ;  .  .  

NULL is #defined to 0

Error: default argument: cannot convert from int to int&


Solution:1

Your example indicates that you are creating a virtual function. Default arguments in virtual (especially pure) functions are not a good idea, because they are not considered when you call an overridden function.

struct A {    virtual void f(int = 4711) = 0;  };    struct B : A {    virtual void f(int) { /* ... */ }  };  

Now, if someone calls f on a B object, he will have to provide the argument - the default isn't used. You would have to duplicate the default argument in the derived class, which creates ugly redundancies. Instead, you can use the non-virtual interface pattern

struct A {    void f(int a) {      int out;      f(a, out);    }      void f(int a, int &out) {      doF(a, out);    }    protected:    virtual void doF(int a, int out&) = 0;  };  

The user can now call f with one, and with two arguments, from whatever class type he calls the function, and the implementers of A don't have to worry about the default argument. By using overloading instead of default arguments, you don't need to break your head around lvalues or temporaries.


Solution:2

The only meaningful way to supply a default argument to a non-const reference is to declare a standalone object with static storage duration and use it as a default argument

int dummy = 0;    ...  virtual int ExecNew(/* whatever */, int& iNewArgument = dummy) = 0;  

Whether it will work for you or not is for you to decide.

Inside the function, if you'll need to detect whether the default argument was used, you may use address comparison

if (&iNewArgument == &dummy)    /* Default argument was used */  


Solution:3

You can't do that. The INewArgument must either be a raw int or a const reference. A non-const reference cannot be used the way you're trying to use it.


Solution:4

In short you're going to have to rework you problem. You can either make your int& a regular int and lose the reference behavior (being able to pass out the changed value) or give up having a default value.


Solution:5

The default has to be lvalue for a non-const reference type, so what try to do above won't work. What you can do is:

namespace detail {    int global;  }    void foo(int &x = detail::global) {}  

or

void bar(const int &x = int(3)) {}  


Solution:6

You say NULL is #defined to 0, so it's a literal value. The parameter is a reference to an int, which means the function would be able to change the value. How do you change the value of a literal?

You need to make it a const reference, or don't make it a reference at all.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »