kiriloff
kiriloff

Reputation: 26335

C++ pass by ref compilation error

With C++, I struggle to understand one compilation error. I have this function, with this given signature:

void MethodNMMS::tryNMSA(double factor, double temperature,double& funcWorst,int& iWorst,      double& funcTry, double* funcEvals)
{
     //...
}

My question concerns argument double& functry (for instance). I call this function tryNMSA() in another function, and I would like functry to be modified during execution of this function. That is why I pass by reference.

Here is the function call:

// other initializations for funcEvals...
double funcTry = 0;
tryNMSA(-1.0,temperature,funcWorst,iWorst,&funcTry,funcEvals);

I put this ampershead because I do want to pass the thing by reference. And that is not permitted. What is wrong, why?

Thanks and regards.

Upvotes: 2

Views: 270

Answers (8)

Agent_L
Agent_L

Reputation: 5411

You can modify a parameter in 2 ways.

Method 1: (reference):

void MethodNMMS::tryNMSA(double& funcTry)
{
    funcTry = funcTry + 1.0;
    //...
}
// other initializations for funcEvals...
double funcTry = 0;
tryNMSA(funcTry);

Method 2: (pointer):

void MethodNMMS::tryNMSA(double* funcTry)
{
    (*funcTry) = (*funcTry) + 1.0;
    //...
}
// other initializations for funcEvals...
double funcTry = 0;
tryNMSA(&funcTry);

Make up your mind and use only one of them, it saves a great deal of confusion.

(actually, here you can use one more method - the return value). It's useful to put emphasis on this one value being main purpose of the function.

double MethodNMMS::tryNMSA(double funcTry)
{
    //...
    return funcTry + 1.0;
}
// other initializations for funcEvals...
double funcTry = 0;
funcTry = tryNMSA(funcTry);

Upvotes: 0

TonyK
TonyK

Reputation: 17114

I won't repeat the other answers. I just wanted to say that this is a recurring issue with learners of C++. The problem is that the & sign has three completely different meanings, and this is not immediately obvious to a beginner:

  1. If x is an l-value, then &x is its address.
  2. If <type> x declares a variable of type <type>, then <type> &x declares a variable of type reference to <type>.
  3. a & b is the bitwise-and operator.

This is similar to the * sign:

  1. If x is a pointer, then *x is its contents.
  2. If <type> x declares a variable of type <type>, then <type> *x declares a variable of type pointer to <type>.
  3. a * b is the multiplication operator.

For some reason, the * operator seems to cause fewer problems than the & operator. Perhaps this is just historical accident: references are newer than pointers.

Upvotes: 0

CosminO
CosminO

Reputation: 5226

Delete the & in front of the parameter.

Info here: http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/PARAMS.html

Reference Parameters

When a parameter is passed by reference, conceptually, the actual parameter itself is passed (and just given a new name -- the name of the corresponding formal parameter). Therefore, any changes made to the formal parameter do affect the actual parameter. For example:

void f(int &n) {
    n++;
}

int main() {
    int x = 2;
    f(x);
    cout << x;  
}

In this example, f's parameter is passed by reference. Therefore, the assignment to n in f is actually changing variable x, so the output of this program is 3.

Upvotes: 0

MK.
MK.

Reputation: 34517

You should omit the ampersand on the call like this:

tryNMSA(-1.0,temperature,funcWorst,iWorst,funcTry,funcEvals);

The ampersand in the method declaration marks it as a reference argument. When you do ampersand in the method call, you are passing the address of the funcTry variable which is immutable and can't be passed by reference, so compiler gives you an error.

Upvotes: 0

Sebastian Mach
Sebastian Mach

Reputation: 39089

Outside of declarations, a single ampersand means address-of, so &foo means address-of foo.

Upvotes: 0

juanchopanza
juanchopanza

Reputation: 227370

By passing &funcTry, you are passing the address of funcTry, which would match a function expecting a pointer to double. Your call should simply be

ryNMSA(-1.0,temperature,funcWorst,iWorst,funcTry,funcEvals);

Upvotes: 2

Mat
Mat

Reputation: 206669

Simply remove the & when you call the function - adding the & means you're trying to pass a pointer.

If you don't put the &, you'll pass a reference. No special syntax necessary.

Upvotes: 2

P&#233;ter T&#246;r&#246;k
P&#233;ter T&#246;r&#246;k

Reputation: 116246

You should not put an ampersand there, as doing so gives a pointer, not a reference to funcTry. Getting a reference to a variable doesn't require any special symbols or operators - just use the name of the variable.

Upvotes: 4

Related Questions