2

I have a problem where some vector returns are empty. Here is the basic setup:

//Foo.h
struct Foo{
    int n;
    double vals[2];
};

//MyClass.h
class MyClass{
private:
    std::vector<Foo> classVector;
public:
    std::vector<Foo> getPair(int i1, int i2);
};

//MyClass.cpp
std::vector<Foo> MyClass::getPair(int i1, int i2)
{
    std::vector<Foo> toReturn(2);
    toReturn[0] = classVector[i1 - 1];
    toReturn[1] = classVector[i2 - 1];
    return toReturn;
}

classVector is a vector that is already initialized and has data in it. I'm basically just trying to obtain two values from that vector and return them using this function. However, when I look at toReturn in debug mode once return is called, the size is reset to zero and the elements that had been copied over (I checked before the return call) are no longer in the vector.

I have a feeling it has to do with a shallow copy being passed on return. I tried creating my own copy constructor for Foo, but I deleted it when it didn't solve the problem.

ewpcasey
  • 63
  • 1
  • 4

1 Answers1

1

The compiler will optimize your code so that the vector toReturn gets moved to the caller's vector.

So if you have:

void someFunc(MyClass& my)
{
    vector<Foo> answer = my.getPair(3,4);
}

After return is called in getPair, the contents of 'toReturn' will now live in 'answer' and 'toReturn' will be empty. As the function is about to return, no further use of 'toReturn' is possible, so there is no need for it to keep its contents. It is more efficient for the 'answer' vector to just grab the guts of the 'toReturn' vector instead of creating new elements in 'answer' and copying each of them from 'toReturn'.

For an explanation of move semantics, see here: What are move semantics?

Community
  • 1
  • 1
Scott Langham
  • 58,735
  • 39
  • 131
  • 204