Home > Back-end >  Running an object call within an object call
Running an object call within an object call

Time:11-12

I have a struct

  struct Stuff {

float something (int& prereq) {
float s = prereq 2;
return s;
}

double something_else(int& prereq_ref, float& thing_ref, float& s_ref ){
s2 = s   thing   h;
return s2;
}

};

Then I run a call in my main loop

float thing = 4;  
int prereq = 2;

int main() {

Stuff item;

    double n = item.something_else(prereq, thing, item.something(prereq));
return 0;

}

The call in main doesn't run, however the following line does

float s = item.something(prereq); 
double n = item.something_else(prereq, thing, s);

Am I missing something obvious? I'd rather not waste memory on what seems to be an unnecessary float.

CodePudding user response:

float& is an lvalue reference type. It can only take values that can be assigned to, such as variables.

float s = item.something(prereq); 
double n = item.something_else(prereq, thing, s);

Here, s is a variable. It has a place in memory and the expression s = ... would be meaningful. On the other hand,

double n = item.something_else(prereq, thing, item.something(prereq));

Here, the value is item.something(prereq), which is not an lvalue. We can't write item.something(prereq) = ...; it doesn't make sense to assign to the return value of that function.

If you're not planning to modify the function arguments, take them by constant reference or by value.

double something_else(const int& prereq_ref, const float& thing_ref, const float& s_ref)

or

double something_else(int prereq_ref, float thing_ref, float s_ref)

for large data like structures or classes, you might consider using const&, but for integers and floats, it's unnecessary overhead and by-value parameters will do fine.

CodePudding user response:

int foo(int & arg);

This function signature says: "I will take a reference to the variable you pass in, and I may change it while computing my return value."

If that statement is not true, then your function signature is wrong, or at least misleading to anyone looking at it. It's also worth noting, that if you compute a temporary, it's not in a variable and so it's ineligible to pass into this function. That is the problem you're running into.

Note, this style of function signature is what's known as an "out" parameter (non-const lvalue reference) because it can be thought of as returning an OUTput through a parameter. This design approach is discouraged if other approaches are available, and so it is actually somewhat rare. Any time you find a function with a non-const reference parameter, be sure it's what you mean.

Compare it to this:

int foo(int arg);

This function says: "I get my own copy and don't care what it came from, variable, reference, temporary, whatever, and I will leave your origianl value alone when computing my return value."

This clearly is what you want to say, so drop the & in your parameter list.

  • Related