Reputation: 1679
I have a problem with the following code:
IntegerSet& IntegerSet::unionOfIntegerSets(IntegerSet a){
IntegerSet result;
for (int i = 0; i < 100; i++){
if ((array[i] == 1) || (a.getElement(i) == 1)){
result.setElement(i, 1);
}
}
return result;
}
The errors are:
reference to local variable 'result' returned [enabled by default]
call of overloaded 'IntegerSet()' is ambiguous
Can you tell me what I'm doing wrong? Thank you!
Header file:
#ifndef INTEGERSET_H_
#define INTEGERSET_H_
class IntegerSet{
private:
int* array;
public:
IntegerSet();
IntegerSet(int, int, int, int, int);
~IntegerSet();
int getElement(int);
void setElement(int, int);
IntegerSet& unionOfIntegerSets(IntegerSet);
IntegerSet insertionOfIntegerSets(IntegerSet);
void setPrint();
};
#endif
What is the workaround for this?
EDIT
IntegerSet IntegerSet::unionOfIntegerSets(IntegerSet a){
IntegerSet result;
for (int i = 0; i < 100; i++){
if ((array[i] == 1) || (a.getElement(i) == 1)){
result.setElement(i, 1);
}
}
return result;
}
The error is:
Upvotes: 0
Views: 1380
Reputation: 471569
The first error is exactly as it says. You are returning a reference to a local variable.
result
is declared on the stack. It will die after the function ends, therefore whatever references to it will becoming invalid and dangling.
As for the second error, we need to see the definition of the IntegerSet
class to see where the ambiguity is.
EDIT : You should also define a copy constructor for your class.
EDIT 2: Okay, I think I figured it out:
Does your the definition for the second constructor looks something like this?
IntegerSet::IntegerSet(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0){
}
I tried this and I got the ambiguous overload call that you got.
In this case, calling the constructor with no parameters can go to either constructor call - hence the ambiguity. So what you should do it get rid of the default value for the first parameter.
Upvotes: 4
Reputation: 16544
You can't return a reference to a local variable. Once the function ends the variable is gone. You need to either return a full copy or change it to this and pass in the variable "result" by reference to the function.
void IntegerSet::unionOfIntegerSets(IntegerSet a, IntegerSet &result){
for (int i = 0; i < 100; i++){
if ((array[i] == 1) || (a.getElement(i) == 1)){
result.setElement(i, 1);
}
}
}
Upvotes: 3
Reputation: 47603
The first error is because, as it said, you are returning a reference to a local variable. Think of reference as a pointer underneath, what you are doing is keeping a reference to a local variable, which means a variable on the stack that after unionOfIntegerSets
finishes it dies. So, the compiler is doing you a great favor by telling you not to do it.
If you have intermediate results, those results need to be copied, which means your return value should be of type IntegerSet
and not IntegerSet &
Your second error is because you have other functions with the same name and you are calling it from somewhere else. The type of the argument you are passing when you are calling the function could be cast to at least two of the function overloads and that is why the compiler cannot understand which of the two (or more) functions you really mean. Since you haven't given any code on that, I will give you an example:
int func(short int a);
int func(int a);
Now if you call:
char c = 'c';
int res = func(c);
C++ can cast char
to both short int
and int
and therefore cannot understand which of the two func
s you want to call.
If you provide more code, I could help you better pin it down.
Upvotes: 2
Reputation: 2433
The problem with returning a local variable is that it is only in scope/valid during the execution of the function, when the function is done the stack frame is thrown away and you can't guarantee anything about the value of that memory.
Upvotes: 2
Reputation: 2640
You cannot return reference to local variable that will be destroyed just after you leave the method. Try returning it by value.
Upvotes: 0