1

On testing the below code snippet, here i am taking one string vector and trying to return it with std::move(vector). If i am using member function signature like this std::vector<std::string>&& getVector() then its working fine. If i am using this std::vector<std::string>& getVector() then its not moving/clearing the vector contents.

Please let me know the correct move semantics to be followed. And please explain difference between both code.

Code :

#include <iostream>
#include <vector>
#include <string>

class VectorMoveDemo
{
public:
    void add(std::string item)
    {
        results_.push_back(item);
    }
    std::vector<std::string>& getVector()
    {
        return std::move(results_);
    }
private:
    std::vector<std::string> results_;
};

int main()
{
    VectorMoveDemo v;
    v.add("Hello ");

    std::cout << "First Time : " << "\n";
    std::vector<std::string> temp = v.getVector();
    for(auto &item : temp)
    {
        std::cout << item << "\n";
    }
    std::cout << "Second Time : " << "\n";

    v.add("World");

    std::vector<std::string> temp2 = v.getVector();
    for(auto &item : temp2)
    {
        std::cout << item << "\n";
    }
}

First:

std::vector<std::string>& getVector()
{
    return std::move(results_);
}

output :

First Time :
Hello
Second Time :
Hello
World

Second

std::vector<std::string>&& getVector()
{
    return std::move(results_);
}

output :

First Time :
Hello
Second Time :
Hello
World

Any help would be really appreciated.

sam_k
  • 5,983
  • 14
  • 76
  • 110
  • 3
    Don't do that. Return by value already gives you rvalue. –  Mar 09 '15 at 06:29
  • What exactly do you want `getVector` to do? Move the vector out of the class to the caller? Then the subsequence `v.add` would be illegal. Please clarify your intent. – fredoverflow Mar 09 '15 at 06:31
  • @FredOverflow I want to clear out previous vector values before adding new values in vectore. Here `getVector()` should empty out the vector contents. – sam_k Mar 09 '15 at 07:02
  • The first version shouldn't compile. Which compiler are you using? Also, you cannot rely on the state of a moved-from vector; it's unspecified. – T.C. Mar 09 '15 at 07:02
  • @T.C. I am using Visual Studio 2013 for C++ application. so visual Studio taking some extra care of this? – sam_k Mar 09 '15 at 07:11

1 Answers1

1

I want to clear out previous vector values before adding new values in vector. Here getVector() should empty out the vector contents.

In that case, there is no need for std::move at all:

std::vector<std::string> getVector()
{
    std::vector<std::string> temp;
    temp.swap(results_);
    return temp;
}

However, you can use std::move in the other member function:

void add(std::string item)
{
    results_.push_back(std::move(item));
}
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • As per my requirement, i have to use move. In requirement its like this : `return reference to vector. Use std::move(vector) to clear vector` – sam_k Mar 09 '15 at 07:55
  • Moreover, I want to understand why i am getting two different outputs for `&` and `&&` . Please elaborate more. I am newbie in C++. – sam_k Mar 09 '15 at 07:56
  • What requirement? Is this homework? If you only write `return std::move(results_);` inside your member function, then the vector is invalidated, and subsequent `push_back`s lead to undefined behaviour. You *could* write `return std::move(temp);` but that would be a pessimization, because it inhibits RVO (return value optimization). So do it only to satisfy your stubborn teacher. – fredoverflow Mar 09 '15 at 07:57
  • Again, the `&` version does not compile on a standards-conforming compiler, and the `&&` version leads to undefined behavior when you call `push_back` afterward. So there is really no point in discussing what output happens to be produced on your system. – fredoverflow Mar 09 '15 at 08:00
  • yes this is homework project and i need to demonstrate std::move usage here only. – sam_k Mar 09 '15 at 14:09
  • If `&` and `&&` are wrong then what is the correct std::move semantics in return function. – sam_k Mar 09 '15 at 14:10
  • Again, if you move `results_` out of `getVector`, then it is illegal to call `add` on the `VectorMoveDemo` afterwards. Either you misunderstood the assignment, or your teacher is wrong. – fredoverflow Mar 09 '15 at 14:40
  • Thanks a lot for your reply, Here i would like to ask you why its illegal? I know vector would became empty or clear after doing std::move. So it also becomes null pointer or something like that? – sam_k Mar 09 '15 at 15:31
  • The question [Is a moved-from vector always empty?](http://stackoverflow.com/questions/17730689/) might be helpful. – fredoverflow Mar 09 '15 at 18:36